Skip to content

Commit

Permalink
get rid of mtp in favor of an ingress
Browse files Browse the repository at this point in the history
  • Loading branch information
QuentinBisson committed Nov 27, 2024
1 parent e5f546c commit b1fb295
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 35 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/onsi/ginkgo/v2 v2.22.0
github.com/onsi/gomega v1.36.0
github.com/pkg/errors v0.9.1
golang.org/x/crypto v0.28.0
golang.org/x/mod v0.22.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.31.3
Expand Down Expand Up @@ -71,7 +72,6 @@ require (
github.com/x448/float16 v0.8.4 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
Expand Down
2 changes: 1 addition & 1 deletion pkg/resource/events-logger-secret/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (r *Reconciler) ReconcileCreate(ctx context.Context, lc loggedcluster.Inter

// Retrieve secret containing credentials
var eventsLoggerCredentialsSecret v1.Secret
err := r.Client.Get(ctx, types.NamespacedName{Name: loggingcredentials.LoggingCredentialsSecretMeta(lc).Name, Namespace: loggingcredentials.LoggingCredentialsSecretMeta(lc).Namespace},
err := r.Client.Get(ctx, types.NamespacedName{Name: loggingcredentials.LoggingCredentialsSecretMeta().Name, Namespace: loggingcredentials.LoggingCredentialsSecretMeta().Namespace},
&eventsLoggerCredentialsSecret)
if err != nil {
return ctrl.Result{}, errors.WithStack(err)
Expand Down
7 changes: 5 additions & 2 deletions pkg/resource/grafana-datasource/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ func (r *Reconciler) ReconcileCreate(ctx context.Context, lc loggedcluster.Inter

// Retrieve secret containing credentials
var loggingCredentialsSecret v1.Secret
err := r.Client.Get(ctx, types.NamespacedName{Name: loggingcredentials.LoggingCredentialsSecretMeta(lc).Name, Namespace: loggingcredentials.LoggingCredentialsSecretMeta(lc).Namespace},
&loggingCredentialsSecret)
var objectKey = types.NamespacedName{
Name: loggingcredentials.LoggingCredentialsSecretMeta().Name,
Namespace: loggingcredentials.LoggingCredentialsSecretMeta().Namespace,
}
err := r.Client.Get(ctx, objectKey, &loggingCredentialsSecret)
if err != nil {
return ctrl.Result{}, errors.WithStack(err)
}
Expand Down
15 changes: 6 additions & 9 deletions pkg/resource/logging-credentials/logging_operator_secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type userCredentials struct {
}

// LoggingCredentialsSecretMeta returns metadata for the logging-operator credentials secret.
func LoggingCredentialsSecretMeta(lc loggedcluster.Interface) metav1.ObjectMeta {
func LoggingCredentialsSecretMeta() metav1.ObjectMeta {
metadata := metav1.ObjectMeta{
Name: LoggingCredentialsName,
Namespace: LoggingCredentialsNamespace,
Expand All @@ -39,7 +39,7 @@ func LoggingCredentialsSecretMeta(lc loggedcluster.Interface) metav1.ObjectMeta
}

// Generate a random 20-characters password
func genPassword() (string, error) {
func generatePassword() (string, error) {
const length = 20

chars := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
Expand All @@ -61,7 +61,7 @@ func genPassword() (string, error) {
// the observabilitybundle application to enable logging.
func GenerateLoggingCredentialsBasicSecret(lc loggedcluster.Interface) *v1.Secret {
secret := v1.Secret{
ObjectMeta: LoggingCredentialsSecretMeta(lc),
ObjectMeta: LoggingCredentialsSecretMeta(),
Data: map[string][]byte{},
}

Expand All @@ -81,21 +81,18 @@ func GetPassword(lc loggedcluster.Interface, credentialsSecret *v1.Secret, usern
return "", errors.New(fmt.Sprintf("Invalid user %s", username))
}

password := userYaml.Password

return string(password), nil
return string(userYaml.Password), nil
}

// AddLoggingCredentials - Add credentials to LoggingCredentials secret if needed
func AddLoggingCredentials(lc loggedcluster.Interface, loggingCredentials *v1.Secret) (bool, error) {

var secretUpdated bool = false

// Always check credentials for "readuser"
if _, ok := loggingCredentials.Data[common.ReadUser]; !ok {
readUser := userCredentials{}

password, err := genPassword()
password, err := generatePassword()
if err != nil {
return false, errors.New("Failed generating read password")
}
Expand All @@ -116,7 +113,7 @@ func AddLoggingCredentials(lc loggedcluster.Interface, loggingCredentials *v1.Se
if _, ok := loggingCredentials.Data[clusterName]; !ok {
clusterUser := userCredentials{}

password, err := genPassword()
password, err := generatePassword()
if err != nil {
return false, errors.New("Failed generating write password")
}
Expand Down
24 changes: 16 additions & 8 deletions pkg/resource/logging-credentials/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ type Reconciler struct {
func (r *Reconciler) ReconcileCreate(ctx context.Context, lc loggedcluster.Interface) (ctrl.Result, error) {
logger := log.FromContext(ctx)

logger.Info("loggingcredentials checking secret", "namespace", LoggingCredentialsSecretMeta(lc).Namespace, "name", LoggingCredentialsSecretMeta(lc).Name)
var objectKey = types.NamespacedName{
Name: LoggingCredentialsSecretMeta().Name,
Namespace: LoggingCredentialsSecretMeta().Namespace,
}
logger.Info("loggingcredentials checking secret", "namespace", objectKey.Namespace, "name", objectKey.Name)

// Start with some empty secret
loggingCredentialsSecret := GenerateLoggingCredentialsBasicSecret(lc)

// Retrieve existing secret if it exists
err := r.Client.Get(ctx, types.NamespacedName{Name: LoggingCredentialsSecretMeta(lc).Name, Namespace: LoggingCredentialsSecretMeta(lc).Namespace}, loggingCredentialsSecret)
err := r.Client.Get(ctx, objectKey, loggingCredentialsSecret)
if err != nil {
if apimachineryerrors.IsNotFound(err) {
logger.Info("loggingcredentials secret not found, initializing one")
Expand All @@ -47,9 +51,9 @@ func (r *Reconciler) ReconcileCreate(ctx context.Context, lc loggedcluster.Inter
}

// Check if metadata has been updated
if !reflect.DeepEqual(loggingCredentialsSecret.ObjectMeta.Labels, LoggingCredentialsSecretMeta(lc).Labels) {
if !reflect.DeepEqual(loggingCredentialsSecret.ObjectMeta.Labels, LoggingCredentialsSecretMeta().Labels) {
logger.Info("loggingCredentials - metatada update required")
loggingCredentialsSecret.ObjectMeta = LoggingCredentialsSecretMeta(lc)
loggingCredentialsSecret.ObjectMeta = LoggingCredentialsSecretMeta()
secretUpdated = true
}

Expand Down Expand Up @@ -77,13 +81,17 @@ func (r *Reconciler) ReconcileCreate(ctx context.Context, lc loggedcluster.Inter
func (r *Reconciler) ReconcileDelete(ctx context.Context, lc loggedcluster.Interface) (ctrl.Result, error) {
logger := log.FromContext(ctx)

logger.Info("loggingcredentials secret delete", "namespace", LoggingCredentialsSecretMeta(lc).Namespace, "name", LoggingCredentialsSecretMeta(lc).Name)
var objectKey = types.NamespacedName{
Name: LoggingCredentialsSecretMeta().Name,
Namespace: LoggingCredentialsSecretMeta().Namespace,
}
logger.Info("loggingcredentials secret delete", "namespace", objectKey.Namespace, "name", objectKey.Name)

// Start with some empty secret
loggingCredentialsSecret := GenerateLoggingCredentialsBasicSecret(lc)

// Retrieve existing secret
err := r.Client.Get(ctx, types.NamespacedName{Name: LoggingCredentialsSecretMeta(lc).Name, Namespace: LoggingCredentialsSecretMeta(lc).Namespace}, loggingCredentialsSecret)
err := r.Client.Get(ctx, objectKey, loggingCredentialsSecret)
if err != nil {
if apimachineryerrors.IsNotFound(err) {
logger.Info("loggingcredentials secret not found, initializing one")
Expand All @@ -97,9 +105,9 @@ func (r *Reconciler) ReconcileDelete(ctx context.Context, lc loggedcluster.Inter
secretUpdated := RemoveLoggingCredentials(lc, loggingCredentialsSecret)

// Check if metadata has been updated
if !reflect.DeepEqual(loggingCredentialsSecret.ObjectMeta.Labels, LoggingCredentialsSecretMeta(lc).Labels) {
if !reflect.DeepEqual(loggingCredentialsSecret.ObjectMeta.Labels, LoggingCredentialsSecretMeta().Labels) {
logger.Info("loggingCredentials - metatada update required")
loggingCredentialsSecret.ObjectMeta = LoggingCredentialsSecretMeta(lc)
loggingCredentialsSecret.ObjectMeta = LoggingCredentialsSecretMeta()
secretUpdated = true
}

Expand Down
9 changes: 6 additions & 3 deletions pkg/resource/logging-secret/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ func (r *Reconciler) ReconcileCreate(ctx context.Context, lc loggedcluster.Inter
logger.Info("logging-secret create")

// Retrieve secret containing credentials
var objectKey = types.NamespacedName{
Name: loggingcredentials.LoggingCredentialsSecretMeta().Name,
Namespace: loggingcredentials.LoggingCredentialsSecretMeta().Namespace,
}
var loggingCredentialsSecret v1.Secret
err := r.Client.Get(ctx, types.NamespacedName{Name: loggingcredentials.LoggingCredentialsSecretMeta(lc).Name, Namespace: loggingcredentials.LoggingCredentialsSecretMeta(lc).Namespace},
&loggingCredentialsSecret)
err := r.Client.Get(ctx, objectKey, &loggingCredentialsSecret)
if err != nil {
return ctrl.Result{}, errors.WithStack(err)
}
Expand All @@ -53,7 +56,7 @@ func (r *Reconciler) ReconcileCreate(ctx context.Context, lc loggedcluster.Inter
// Check if secret already exists.
logger.Info("logging-secret - getting", "namespace", desiredLoggingSecret.GetNamespace(), "name", desiredLoggingSecret.GetName())
var currentLoggingSecret v1.Secret
err = r.Client.Get(ctx, types.NamespacedName{Name: desiredLoggingSecret.GetName(), Namespace: desiredLoggingSecret.GetNamespace()}, &currentLoggingSecret)
err = r.Client.Get(ctx, objectKey, &currentLoggingSecret)
if err != nil {
if apimachineryerrors.IsNotFound(err) {
logger.Info("logging-secret not found, creating")
Expand Down
70 changes: 70 additions & 0 deletions pkg/resource/loki-ingress-auth-secret/ingress-auth-secret.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package lokiingressauthsecret

import (
"github.com/pkg/errors"
"golang.org/x/crypto/bcrypt"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/giantswarm/logging-operator/pkg/common"
loggedcluster "github.com/giantswarm/logging-operator/pkg/logged-cluster"
loggingcredentials "github.com/giantswarm/logging-operator/pkg/resource/logging-credentials"
)

const (
//#nosec G101
lokiIngressAuthSecretName = "loki-ingress-auth"
lokiIngressAuthSecretNamespace = "loki"
// DefaultReadOrgIDs - make sure to have at least 2 tenants, to prevent writing with this user
DefaultReadOrgIDs = "giantswarm|default"
)

// lokiIngressAuthSecretMetadata returns metadata for the loki ingress auth secret metadata
func lokiIngressAuthSecretMetadata() metav1.ObjectMeta {
metadata := metav1.ObjectMeta{
Name: lokiIngressAuthSecretName,
Namespace: lokiIngressAuthSecretNamespace,
Labels: map[string]string{},
}

common.AddCommonLabels(metadata.Labels)
return metadata
}

func lokiIngressAuthSecret() v1.Secret {
return v1.Secret{
ObjectMeta: lokiIngressAuthSecretMetadata(),
}
}

// listWriteUsers returns a map of users found in a credentialsSecret
func listWriteUsers(credentialsSecret *v1.Secret) []string {
var usersList []string
for myUser := range credentialsSecret.Data {
// bypass read user
if myUser != common.ReadUser {
usersList = append(usersList, myUser)
}
}

return usersList
}

// generateLokiIngressAuthSecret returns a secret for the loki ingress auth
func generateLokiIngressAuthSecret(lc loggedcluster.Interface, credentialsSecret *v1.Secret) (map[string][]byte, error) {
users := make(map[string][]byte)
// Loop on write users
for _, writeUser := range listWriteUsers(credentialsSecret) {
writePassword, err := loggingcredentials.GetPassword(lc, credentialsSecret, writeUser)
if err != nil {
return nil, errors.WithStack(err)
}
password, err := bcrypt.GenerateFromPassword([]byte(writePassword), bcrypt.DefaultCost)
if err != nil {
return nil, errors.WithStack(err)
}
users[writeUser] = password
}

return users, nil
}
77 changes: 77 additions & 0 deletions pkg/resource/loki-ingress-auth-secret/reconciler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package lokiingressauthsecret

import (
"context"

"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"

loggedcluster "github.com/giantswarm/logging-operator/pkg/logged-cluster"
loggingcredentials "github.com/giantswarm/logging-operator/pkg/resource/logging-credentials"

ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/log"
)

// Reconciler implements a reconciler.Interface to handle
// loki ingress auth secret: a secret for the loki ingress that adds support for basic auth for the write path
type Reconciler struct {
client.Client
}

// ReconcileCreate ensures loki ingress auth map is created with the right credentials on CAPI
func (r *Reconciler) ReconcileCreate(ctx context.Context, lc loggedcluster.Interface) (ctrl.Result, error) {
// If we are not on CAPI, we don't need to create the secret as we are using the multi-tenant-proxy
if !lc.IsCAPI() {
return ctrl.Result{}, nil
}

return r.createOrUpdateSecret(ctx, lc)
}

// ReconcileDelete - Delete the loki ingress auth secret on capi
func (r *Reconciler) ReconcileDelete(ctx context.Context, lc loggedcluster.Interface) (ctrl.Result, error) {
// If we are not on CAPI, we don't need to create the secret as we are using the multi-tenant-proxy
if !lc.IsCAPI() {
return ctrl.Result{}, nil
}

return r.createOrUpdateSecret(ctx, lc)
}

func (r *Reconciler) createOrUpdateSecret(ctx context.Context, lc loggedcluster.Interface) (ctrl.Result, error) {
logger := log.FromContext(ctx)

// Retrieve currently generated write path credentials
var objectKey = types.NamespacedName{
Name: loggingcredentials.LoggingCredentialsSecretMeta().Name,
Namespace: loggingcredentials.LoggingCredentialsSecretMeta().Namespace,
}

var writePathCredentials v1.Secret
if err := r.Client.Get(ctx, objectKey, &writePathCredentials); err != nil {
return ctrl.Result{}, errors.WithStack(err)
}

secret := lokiIngressAuthSecret()
_, err := controllerutil.CreateOrUpdate(ctx, r.Client, &secret, func() error {
// Generate loki ingress auth secret
data, err := generateLokiIngressAuthSecret(lc, &writePathCredentials)
if err != nil {
logger.Error(err, "failed to generate loki ingress auth secret")
return errors.WithStack(err)
}
secret.Data = data

return nil
})
if err != nil {
logger.Error(err, "failed to create loki ingress auth secret")
return ctrl.Result{}, errors.WithStack(err)
}

return ctrl.Result{}, nil
}
Loading

0 comments on commit b1fb295

Please sign in to comment.