Skip to content

Commit

Permalink
(chore): uses org name as dex resource namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
abhijith-darshan committed Feb 5, 2025
1 parent 43a284b commit cdc76eb
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 100 deletions.
4 changes: 2 additions & 2 deletions pkg/controllers/organization/dex.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (r *OrganizationReconciler) reconcileDexConnector(ctx context.Context, org
if err != nil {
return err
}
return r.Dexter.CreateUpdateConnector(ctx, r.Client, org, configByte, org.Name)
return r.Dexter.CreateUpdateConnector(ctx, r.Client, org, configByte)
}

func (r *OrganizationReconciler) enqueueOrganizationForReferencedSecret(_ context.Context, o client.Object) []ctrl.Request {
Expand Down Expand Up @@ -88,7 +88,7 @@ func (r *OrganizationReconciler) discoverOIDCRedirectURL(ctx context.Context, or
}

func (r *OrganizationReconciler) reconcileOAuth2Client(ctx context.Context, org *greenhousesapv1alpha1.Organization) error {
return r.Dexter.CreateUpdateOauth2Client(ctx, r.Client, org, org.Name)
return r.Dexter.CreateUpdateOauth2Client(ctx, r.Client, org)
}

func ensureCallbackURL(url string) string {
Expand Down
21 changes: 8 additions & 13 deletions pkg/dex/store/k8s_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,12 @@ func (k *k8sDex) GetBackend() string {
}

// CreateUpdateConnector - creates or updates a dex connector in dex kubernetes storage backend
func (k *k8sDex) CreateUpdateConnector(ctx context.Context, k8sClient client.Client, org *greenhouseapisv1alpha1.Organization, configByte []byte, namespace string) (err error) {
func (k *k8sDex) CreateUpdateConnector(ctx context.Context, k8sClient client.Client, org *greenhouseapisv1alpha1.Organization, configByte []byte) (err error) {
var result clientutil.OperationResult
var dexConnector = new(dexapi.Connector)
dexConnector.Namespace = namespace
dexConnector.ObjectMeta.Name = org.GetName()
namespaceName := org.GetName()
dexConnector.SetName(namespaceName)
dexConnector.SetNamespace(namespaceName)
result, err = clientutil.CreateOrPatch(ctx, k8sClient, dexConnector, func() error {
dexConnector.DexConnector.Type = dexConnectorTypeGreenhouse
dexConnector.DexConnector.Name = cases.Title(language.English).String(org.Name)
Expand All @@ -96,16 +97,15 @@ func (k *k8sDex) CreateUpdateConnector(ctx context.Context, k8sClient client.Cli
}

// CreateUpdateOauth2Client - creates or updates an oauth2 client in dex kubernetes storage backend
func (k *k8sDex) CreateUpdateOauth2Client(ctx context.Context, k8sClient client.Client, org *greenhouseapisv1alpha1.Organization, namespace string) error {
func (k *k8sDex) CreateUpdateOauth2Client(ctx context.Context, k8sClient client.Client, org *greenhouseapisv1alpha1.Organization) error {
var oAuth2Client = new(dexapi.OAuth2Client)
oAuth2Client.ObjectMeta.Name = encodedOAuth2ClientName(org.Name)
oAuth2Client.ObjectMeta.Namespace = namespace
generatedClientSecret := getDeterministicSecret(org.Name, org.GetUID())
namespaceName := org.GetName()
oAuth2Client.SetName(encodedOAuth2ClientName(namespaceName))
oAuth2Client.SetNamespace(namespaceName)

result, err := clientutil.CreateOrPatch(ctx, k8sClient, oAuth2Client, func() error {
oAuth2Client.Client.Public = true
oAuth2Client.Client.ID = org.Name
oAuth2Client.Secret = generatedClientSecret
oAuth2Client.Client.Name = org.Name
for _, requiredRedirectURL := range []string{
"http://localhost:8085",
Expand All @@ -127,11 +127,6 @@ func (k *k8sDex) CreateUpdateOauth2Client(ctx context.Context, k8sClient client.
log.FromContext(ctx).Info("updated oauth2client", "namespace", oAuth2Client.Namespace, "name", oAuth2Client.GetName())
}

secret := prepareClientSecret(namespace, org.Name, generatedClientSecret)
err = writeCredentialsToNamespace(ctx, k8sClient, org, secret)
if err != nil {
return err
}
return nil
}

Expand Down
17 changes: 3 additions & 14 deletions pkg/dex/store/pg_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (p *pgDex) GetBackend() string {
}

// CreateUpdateConnector - creates or updates a dex connector in dex postgres storage backend
func (p *pgDex) CreateUpdateConnector(ctx context.Context, _ client.Client, org *greenhouseapisv1alpha1.Organization, configByte []byte, _ string) error {
func (p *pgDex) CreateUpdateConnector(ctx context.Context, _ client.Client, org *greenhouseapisv1alpha1.Organization, configByte []byte) error {
oidcConnector, err := p.storage.GetConnector(org.Name)
if err != nil && errors.Is(err, storage.ErrNotFound) {
if err = p.storage.CreateConnector(ctx, storage.Connector{
Expand Down Expand Up @@ -99,18 +99,15 @@ func (p *pgDex) CreateUpdateConnector(ctx context.Context, _ client.Client, org
}

// CreateUpdateOauth2Client - creates or updates an oauth2 client in dex postgres storage backend
func (p *pgDex) CreateUpdateOauth2Client(ctx context.Context, k8sClient client.Client, org *greenhouseapisv1alpha1.Organization, namespace string) error {
generatedClientSecret := getDeterministicSecret(org.Name, org.GetUID())
func (p *pgDex) CreateUpdateOauth2Client(ctx context.Context, _ client.Client, org *greenhouseapisv1alpha1.Organization) error {
oAuthClient, err := p.storage.GetClient(org.Name)
if err != nil && errors.Is(err, storage.ErrNotFound) {
if err = p.storage.CreateClient(ctx, storage.Client{
Public: true,
ID: org.Name,
Secret: generatedClientSecret,
Name: org.Name,
RedirectURIs: []string{
"http://localhost:8085",
"http://localhost:8000",
"https://dashboard." + common.DNSDomain,
fmt.Sprintf("https://%s.dashboard.%s", org.Name, common.DNSDomain),
},
Expand All @@ -123,14 +120,13 @@ func (p *pgDex) CreateUpdateOauth2Client(ctx context.Context, k8sClient client.C
if err != nil {
log.FromContext(ctx).Error(err, "failed to get oauth2client", "name", org.Name)
}

err = p.storage.UpdateClient(oAuthClient.Name, func(authClient storage.Client) (storage.Client, error) {
authClient.Public = true
authClient.ID = org.Name
authClient.Secret = generatedClientSecret
authClient.Name = org.Name
for _, requiredRedirectURL := range []string{
"http://localhost:8085",
"http://localhost:8000",
"https://dashboard." + common.DNSDomain,
fmt.Sprintf("https://%s.dashboard.%s", org.Name, common.DNSDomain),
} {
Expand All @@ -141,13 +137,6 @@ func (p *pgDex) CreateUpdateOauth2Client(ctx context.Context, k8sClient client.C
if err != nil {
return err
}
// write the client credentials to the organization namespace
secret := prepareClientSecret(namespace, org.Name, generatedClientSecret)
err = writeCredentialsToNamespace(ctx, k8sClient, org, secret)
if err != nil {
return err
}
log.FromContext(ctx).Info("updated oauth2client", "name", org.Name)
return nil
}

Expand Down
73 changes: 2 additions & 71 deletions pkg/dex/store/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,11 @@ package store

import (
"context"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"log/slog"

"github.com/dexidp/dex/storage"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
controllerruntime "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"

greenhouseapisv1alpha1 "github.com/cloudoperators/greenhouse/pkg/apis/greenhouse/v1alpha1"
)
Expand All @@ -25,15 +18,13 @@ const (
Postgres = "postgres"
K8s = "kubernetes"
dexConnectorTypeGreenhouse = "greenhouse-oidc"
clientIDKey = "clientID"
clientSecretKey = "clientSecret"
)

// Dexter - dex storage adapter interface
// Supported backends: Postgres, K8s
type Dexter interface {
CreateUpdateConnector(ctx context.Context, k8sClient client.Client, org *greenhouseapisv1alpha1.Organization, configByte []byte, namespace string) error
CreateUpdateOauth2Client(ctx context.Context, k8sClient client.Client, org *greenhouseapisv1alpha1.Organization, namespace string) error
CreateUpdateConnector(ctx context.Context, k8sClient client.Client, org *greenhouseapisv1alpha1.Organization, configByte []byte) error
CreateUpdateOauth2Client(ctx context.Context, k8sClient client.Client, org *greenhouseapisv1alpha1.Organization) error
GetStorage() storage.Storage
GetBackend() string
Close() error
Expand All @@ -58,63 +49,3 @@ func NewDexStorageFactory(logger *slog.Logger, backend string) (Dexter, error) {
return nil, fmt.Errorf("unknown dexStorage backend: %s", backend)
}
}

// getDeterministicSecret - generate a deterministic secret based on the clientID and secretKey
func getDeterministicSecret(clientID string, secretKey types.UID) string {
h := hmac.New(sha256.New, []byte(secretKey))
h.Write([]byte(clientID))
return hex.EncodeToString(h.Sum(nil))[:32]
}

// prepareClientSecret - create a coreV1 secret with the clientID and secret
func prepareClientSecret(namespace, clientID, clientSecret string) *corev1.Secret {
secret := new(corev1.Secret)
secret.SetName(clientID + "-dex-secrets")
secret.SetNamespace(namespace)
secret.Data = map[string][]byte{
clientIDKey: []byte(clientID),
clientSecretKey: []byte(clientSecret),
}
return secret
}

// writeCredentialsToNamespace - write the client credentials to the organization namespace
// if the secret already exists, update the secret
// set organization as the owner reference for the secret
func writeCredentialsToNamespace(ctx context.Context, cl client.Client, org *greenhouseapisv1alpha1.Organization, secret *corev1.Secret) error {
existing := &corev1.Secret{}
err := cl.Get(ctx, types.NamespacedName{Name: secret.Name, Namespace: secret.Namespace}, existing)
if err != nil {
if client.IgnoreNotFound(err) != nil {
log.FromContext(ctx).Error(err, "unable to get dex client credentials", "name", secret.Name, "namespace", secret.Namespace)
return err
}
// if not found, create the secret with owner reference
// set the owner reference
err = controllerruntime.SetControllerReference(org, secret, cl.Scheme())
if err != nil {
log.FromContext(ctx).Error(err, "unable to set controller reference for dex client credentials", "name", secret.Name, "namespace", secret.Namespace)
return err
}
err = cl.Create(ctx, secret)
if err != nil {
log.FromContext(ctx).Error(err, "unable to create dex client credentials", "name", secret.Name, "namespace", secret.Namespace)
return err
}
return nil
}

existing.Data[clientIDKey] = secret.Data[clientIDKey]
existing.Data[clientSecretKey] = secret.Data[clientSecretKey]
err = controllerruntime.SetControllerReference(org, existing, cl.Scheme())
if err != nil {
log.FromContext(ctx).Error(err, "unable to create / patch dex client credentials", "name", secret.Name, "namespace", secret.Namespace)
return err
}
err = cl.Update(ctx, existing)
if err != nil {
log.FromContext(ctx).Error(err, "unable to update dex client credentials", "name", secret.Name, "namespace", secret.Namespace)
return err
}
return nil
}

0 comments on commit cdc76eb

Please sign in to comment.