-
Notifications
You must be signed in to change notification settings - Fork 1
feat: idp resource creation #227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
63a4ebb
feat: added idp resource creation
OlegErshov efb720e
fixed tests
OlegErshov 255dc4f
feat: added workspace type patching
OlegErshov a2f013a
feat: removed secret waiting functionality
OlegErshov 17ca9c5
feat: removed realm subroutine
OlegErshov 5c9a8dd
feat: updated client id fetching
OlegErshov 6ac8c7b
fix: improved timout and secret error handling
OlegErshov 48d1840
fix: added waiting for finalizers functionality in integration tests
OlegErshov 9e7ee49
chore: refactored idp resource creation
OlegErshov 38baad0
chore: refactored client id fetching
OlegErshov d94f9be
fix: replaces http schema with https for logout uris
OlegErshov 4e3e757
chore: refactored idp subroutine initialization
OlegErshov 11d478c
chore: removed unused fields in config
OlegErshov e82eb27
chore: updated secret's naming in tests
OlegErshov 00c6096
chore: addressed other coderabbit comments
OlegErshov a4e02dd
chore: increased timeout
OlegErshov 8690c3b
Update internal/subroutine/idp.go
OlegErshov 5755207
fix: used patch call instead of createOrUpdate
OlegErshov 908dd14
fix: added equality check before patching workspace type
OlegErshov da02ebd
feat: simplified client id look up
OlegErshov 2318d08
fix: updated tests
OlegErshov a8c5291
chore: added apiexport endpoint slice name config variable back
OlegErshov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| package subroutine | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "slices" | ||
| "strings" | ||
|
|
||
| kcpv1alpha1 "github.com/kcp-dev/kcp/sdk/apis/core/v1alpha1" | ||
| accountv1alpha1 "github.com/platform-mesh/account-operator/api/v1alpha1" | ||
| "github.com/platform-mesh/golang-commons/controller/lifecycle/runtimeobject" | ||
| lifecyclesubroutine "github.com/platform-mesh/golang-commons/controller/lifecycle/subroutine" | ||
| "github.com/rs/zerolog/log" | ||
|
|
||
| corev1 "k8s.io/api/core/v1" | ||
| "k8s.io/apimachinery/pkg/api/meta" | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| "k8s.io/apimachinery/pkg/types" | ||
|
|
||
| "github.com/platform-mesh/golang-commons/errors" | ||
| ctrl "sigs.k8s.io/controller-runtime" | ||
| "sigs.k8s.io/controller-runtime/pkg/client" | ||
| "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" | ||
| mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager" | ||
|
|
||
| "github.com/platform-mesh/security-operator/api/v1alpha1" | ||
| "github.com/platform-mesh/security-operator/internal/config" | ||
| ) | ||
|
|
||
| func NewIDPSubroutine(orgsClient client.Client, mgr mcmanager.Manager, cfg config.Config) *IDPSubroutine { | ||
| return &IDPSubroutine{ | ||
| orgsClient: orgsClient, | ||
| mgr: mgr, | ||
| additionalRedirectURLs: cfg.IDP.AdditionalRedirectURLs, | ||
| baseDomain: cfg.BaseDomain, | ||
| } | ||
| } | ||
|
|
||
| var _ lifecyclesubroutine.Subroutine = &IDPSubroutine{} | ||
|
|
||
| type IDPSubroutine struct { | ||
| orgsClient client.Client | ||
| mgr mcmanager.Manager | ||
| additionalRedirectURLs []string | ||
| baseDomain string | ||
| } | ||
|
|
||
| func (w *IDPSubroutine) Finalize(ctx context.Context, instance runtimeobject.RuntimeObject) (ctrl.Result, errors.OperatorError) { | ||
| return ctrl.Result{}, nil | ||
| } | ||
|
|
||
| func (w *IDPSubroutine) Finalizers(_ runtimeobject.RuntimeObject) []string { | ||
| return nil | ||
| } | ||
|
|
||
| func (w *IDPSubroutine) GetName() string { return "IDPSubroutine" } | ||
|
|
||
| func (w *IDPSubroutine) Process(ctx context.Context, instance runtimeobject.RuntimeObject) (ctrl.Result, errors.OperatorError) { | ||
| lc := instance.(*kcpv1alpha1.LogicalCluster) | ||
|
|
||
| workspaceName := getWorkspaceName(lc) | ||
| if workspaceName == "" { | ||
| return ctrl.Result{}, errors.NewOperatorError(fmt.Errorf("failed to get workspace name"), true, false) | ||
| } | ||
|
|
||
| cl, err := w.mgr.ClusterFromContext(ctx) | ||
| if err != nil { | ||
| return ctrl.Result{}, errors.NewOperatorError(fmt.Errorf("failed to get cluster from context %w", err), true, true) | ||
| } | ||
|
|
||
| var account accountv1alpha1.Account | ||
| err = w.orgsClient.Get(ctx, types.NamespacedName{Name: workspaceName}, &account) | ||
| if err != nil { | ||
| return ctrl.Result{}, errors.NewOperatorError(fmt.Errorf("failed to get account resource %w", err), true, true) | ||
| } | ||
|
|
||
| if account.Spec.Type != accountv1alpha1.AccountTypeOrg { | ||
| log.Debug().Str("workspace", workspaceName).Msg("account is not of type organization, skipping idp creation") | ||
| return ctrl.Result{}, nil | ||
| } | ||
|
|
||
| clientConfig := v1alpha1.IdentityProviderClientConfig{ | ||
| ClientName: workspaceName, | ||
| ClientType: v1alpha1.IdentityProviderClientTypeConfidential, | ||
| RedirectURIs: append(w.additionalRedirectURLs, fmt.Sprintf("https://%s.%s/*", workspaceName, w.baseDomain)), | ||
| PostLogoutRedirectURIs: []string{fmt.Sprintf("https://%s.%s/logout*", workspaceName, w.baseDomain)}, | ||
| SecretRef: corev1.SecretReference{ | ||
| Name: fmt.Sprintf("portal-client-secret-%s-%s", workspaceName, workspaceName), | ||
| Namespace: "default", | ||
| }, | ||
OlegErshov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| idp := &v1alpha1.IdentityProviderConfiguration{ObjectMeta: metav1.ObjectMeta{Name: workspaceName}} | ||
| _, err = controllerutil.CreateOrUpdate(ctx, cl.GetClient(), idp, func() error { | ||
| clientIdx := slices.IndexFunc(idp.Spec.Clients, func(c v1alpha1.IdentityProviderClientConfig) bool { | ||
| return c.ClientName == clientConfig.ClientName | ||
| }) | ||
| if clientIdx != -1 { | ||
| idp.Spec.Clients[clientIdx].RedirectURIs = clientConfig.RedirectURIs | ||
| idp.Spec.Clients[clientIdx].ClientType = clientConfig.ClientType | ||
| idp.Spec.Clients[clientIdx].SecretRef = clientConfig.SecretRef | ||
| idp.Spec.Clients[clientIdx].PostLogoutRedirectURIs = clientConfig.PostLogoutRedirectURIs | ||
| return nil | ||
| } | ||
|
|
||
| idp.Spec.Clients = append(idp.Spec.Clients, clientConfig) | ||
| return nil | ||
| }) | ||
| if err != nil { | ||
| return ctrl.Result{}, errors.NewOperatorError(fmt.Errorf("failed to create idp resource %w", err), true, true) | ||
| } | ||
|
|
||
| log.Info().Str("workspace", workspaceName).Msg("idp configuration resource is created") | ||
|
|
||
| if err := cl.GetClient().Get(ctx, types.NamespacedName{Name: workspaceName}, idp); err != nil { | ||
| return ctrl.Result{}, errors.NewOperatorError(fmt.Errorf("failed to get idp resource %w", err), true, true) | ||
| } | ||
| if !meta.IsStatusConditionTrue(idp.GetConditions(), "Ready") { | ||
| return ctrl.Result{}, errors.NewOperatorError(fmt.Errorf("idp resource is not ready yet"), true, false) | ||
| } | ||
|
|
||
| log.Info().Str("workspace", workspaceName).Msg("idp resource is ready") | ||
| return ctrl.Result{}, nil | ||
| } | ||
|
|
||
| func getWorkspaceName(lc *kcpv1alpha1.LogicalCluster) string { | ||
| if path, ok := lc.Annotations["kcp.io/path"]; ok { | ||
| pathElements := strings.Split(path, ":") | ||
| return pathElements[len(pathElements)-1] | ||
| } | ||
| return "" | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.