Skip to content

Commit

Permalink
CLOUDP-280012: Add http dry run transport for Atlas (#2026)
Browse files Browse the repository at this point in the history
* add dryrun transport

* add dry run recorder to atlas provider

* add object to workflow context

* wire dry running in controllers

* fix unit tests expecting wrong context
  • Loading branch information
s-urbaniak authored Jan 10, 2025
1 parent 86ed538 commit 6320166
Show file tree
Hide file tree
Showing 29 changed files with 371 additions and 82 deletions.
64 changes: 40 additions & 24 deletions internal/controller/atlas/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ import (
"runtime"
"strings"

"go.mongodb.org/atlas-sdk/v20231115008/admin"
"github.com/mongodb-forks/digest"
adminv20231115008 "go.mongodb.org/atlas-sdk/v20231115008/admin"
adminv20241113001 "go.mongodb.org/atlas-sdk/v20241113001/admin"
"go.mongodb.org/atlas/mongodbatlas"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client"

//v20241113001
"github.com/mongodb/mongodb-atlas-kubernetes/v2/api"
akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/api/v1"
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/dryrun"
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/httputil"
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/version"
)
Expand All @@ -31,21 +33,22 @@ const (

type Provider interface {
Client(ctx context.Context, secretRef *client.ObjectKey, log *zap.SugaredLogger) (*mongodbatlas.Client, string, error)
SdkClient(ctx context.Context, secretRef *client.ObjectKey, log *zap.SugaredLogger) (*admin.APIClient, string, error)
SdkClient(ctx context.Context, secretRef *client.ObjectKey, log *zap.SugaredLogger) (*adminv20231115008.APIClient, string, error)
SdkClientSet(ctx context.Context, secretRef *client.ObjectKey, log *zap.SugaredLogger) (*ClientSet, string, error)
IsCloudGov() bool
IsResourceSupported(resource api.AtlasCustomResource) bool
}

type ClientSet struct {
//SdkClient20231115008 *admin.APIClient
SdkClient20231115008 *adminv20231115008.APIClient
SdkClient20241113001 *adminv20241113001.APIClient
}

type ProductionProvider struct {
k8sClient client.Client
domain string
globalSecretRef client.ObjectKey
dryRunRecorder record.EventRecorder
}

type credentialsSecret struct {
Expand All @@ -54,11 +57,12 @@ type credentialsSecret struct {
PrivateKey string
}

func NewProductionProvider(atlasDomain string, globalSecretRef client.ObjectKey, k8sClient client.Client) *ProductionProvider {
func NewProductionProvider(atlasDomain string, globalSecretRef client.ObjectKey, k8sClient client.Client, dryRunRecorder record.EventRecorder) *ProductionProvider {
return &ProductionProvider{
k8sClient: k8sClient,
domain: atlasDomain,
globalSecretRef: globalSecretRef,
dryRunRecorder: dryRunRecorder,
}
}

Expand Down Expand Up @@ -111,7 +115,9 @@ func (p *ProductionProvider) Client(ctx context.Context, secretRef *client.Objec
httputil.Digest(secretData.PublicKey, secretData.PrivateKey),
httputil.LoggingTransport(log),
}
httpClient, err := httputil.DecorateClient(&http.Client{Transport: http.DefaultTransport}, clientCfg...)

transport := p.newDryRunTransport(http.DefaultTransport)
httpClient, err := httputil.DecorateClient(&http.Client{Transport: transport}, clientCfg...)
if err != nil {
return nil, "", err
}
Expand All @@ -121,48 +127,58 @@ func (p *ProductionProvider) Client(ctx context.Context, secretRef *client.Objec
return c, secretData.OrgID, err
}

func (p *ProductionProvider) SdkClient(ctx context.Context, secretRef *client.ObjectKey, log *zap.SugaredLogger) (*admin.APIClient, string, error) {
secretData, err := getSecrets(ctx, p.k8sClient, secretRef, &p.globalSecretRef)
func (p *ProductionProvider) SdkClient(ctx context.Context, secretRef *client.ObjectKey, log *zap.SugaredLogger) (*adminv20231115008.APIClient, string, error) {
clientSet, orgID, err := p.SdkClientSet(ctx, secretRef, log)
if err != nil {
return nil, "", err
}

// TODO review we need add a custom logger to http client
//httpClientWithCustomLogger := http.DefaultClient
//err = httputil.LoggingTransport(log)(http.DefaultClient)
//if err != nil {
// return nil, "", err
//}
// Special case: SdkClient only returns the v20231115008 client.
return clientSet.SdkClient20231115008, orgID, nil
}

c, err := NewClient(p.domain, secretData.PublicKey, secretData.PrivateKey)
func (p *ProductionProvider) SdkClientSet(ctx context.Context, secretRef *client.ObjectKey, log *zap.SugaredLogger) (*ClientSet, string, error) {
secretData, err := getSecrets(ctx, p.k8sClient, secretRef, &p.globalSecretRef)
if err != nil {
return nil, "", err
}

return c, secretData.OrgID, nil
}
var transport http.RoundTripper = digest.NewTransport(secretData.PublicKey, secretData.PrivateKey)
transport = p.newDryRunTransport(transport)
transport = httputil.NewLoggingTransport(log, false, transport)

func (p *ProductionProvider) SdkClientSet(ctx context.Context, secretRef *client.ObjectKey, log *zap.SugaredLogger) (*ClientSet, string, error) {
secretData, err := getSecrets(ctx, p.k8sClient, secretRef, &p.globalSecretRef)
httpClient := &http.Client{Transport: transport}

clientv20231115008, err := adminv20231115008.NewClient(
adminv20231115008.UseBaseURL(p.domain),
adminv20231115008.UseHTTPClient(httpClient),
adminv20231115008.UseUserAgent(operatorUserAgent()))
if err != nil {
return nil, "", err
}

// Instead of constantly extending the interface above, consider grouping all SDK Clients here
// New SDK (v20241113001) SDK
c2024, err := adminv20241113001.NewClient(
clientv20241113001, err := adminv20241113001.NewClient(
adminv20241113001.UseBaseURL(p.domain),
adminv20241113001.UseDigestAuth(secretData.PublicKey, secretData.PrivateKey),
adminv20241113001.UseHTTPClient(httpClient),
adminv20241113001.UseUserAgent(operatorUserAgent()))
if err != nil {
return nil, "", err
}

return &ClientSet{
SdkClient20241113001: c2024,
SdkClient20231115008: clientv20231115008,
SdkClient20241113001: clientv20241113001,
}, secretData.OrgID, nil
}

func (p *ProductionProvider) newDryRunTransport(delegate http.RoundTripper) http.RoundTripper {
if p.dryRunRecorder == nil {
return delegate
}

return dryrun.NewDryRunTransport(p.dryRunRecorder, delegate)
}

func getSecrets(ctx context.Context, k8sClient client.Client, secretRef, fallbackRef *client.ObjectKey) (*credentialsSecret, error) {
if secretRef == nil {
secretRef = fallbackRef
Expand Down
12 changes: 6 additions & 6 deletions internal/controller/atlas/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestProvider_Client(t *testing.T) {
Build()

t.Run("should return Atlas API client and organization id using global secret", func(t *testing.T) {
p := NewProductionProvider("https://cloud.mongodb.com/", client.ObjectKey{Name: "api-secret", Namespace: "default"}, k8sClient)
p := NewProductionProvider("https://cloud.mongodb.com/", client.ObjectKey{Name: "api-secret", Namespace: "default"}, k8sClient, nil)

c, id, err := p.Client(context.Background(), nil, zaptest.NewLogger(t).Sugar())
assert.NoError(t, err)
Expand All @@ -52,7 +52,7 @@ func TestProvider_Client(t *testing.T) {
})

t.Run("should return Atlas API client and organization id using connection secret", func(t *testing.T) {
p := NewProductionProvider("https://cloud.mongodb.com/", client.ObjectKey{Name: "global-secret", Namespace: "default"}, k8sClient)
p := NewProductionProvider("https://cloud.mongodb.com/", client.ObjectKey{Name: "global-secret", Namespace: "default"}, k8sClient, nil)

c, id, err := p.Client(context.Background(), &client.ObjectKey{Name: "api-secret", Namespace: "default"}, zaptest.NewLogger(t).Sugar())
assert.NoError(t, err)
Expand All @@ -63,17 +63,17 @@ func TestProvider_Client(t *testing.T) {

func TestProvider_IsCloudGov(t *testing.T) {
t.Run("should return false for invalid domain", func(t *testing.T) {
p := NewProductionProvider("http://x:namedport", client.ObjectKey{}, nil)
p := NewProductionProvider("http://x:namedport", client.ObjectKey{}, nil, nil)
assert.False(t, p.IsCloudGov())
})

t.Run("should return false for commercial Atlas domain", func(t *testing.T) {
p := NewProductionProvider("https://cloud.mongodb.com/", client.ObjectKey{}, nil)
p := NewProductionProvider("https://cloud.mongodb.com/", client.ObjectKey{}, nil, nil)
assert.False(t, p.IsCloudGov())
})

t.Run("should return true for Atlas for government domain", func(t *testing.T) {
p := NewProductionProvider("https://cloud.mongodbgov.com/", client.ObjectKey{}, nil)
p := NewProductionProvider("https://cloud.mongodbgov.com/", client.ObjectKey{}, nil, nil)
assert.True(t, p.IsCloudGov())
})
}
Expand Down Expand Up @@ -164,7 +164,7 @@ func TestProvider_IsResourceSupported(t *testing.T) {

for desc, data := range dataProvider {
t.Run(desc, func(t *testing.T) {
p := NewProductionProvider(data.domain, client.ObjectKey{}, nil)
p := NewProductionProvider(data.domain, client.ObjectKey{}, nil, nil)
assert.Equal(t, data.expectation, p.IsResourceSupported(data.resource))
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (r *AtlasBackupCompliancePolicyReconciler) Reconcile(ctx context.Context, r
}

conditions := akov2.InitCondition(bcp, api.FalseCondition(api.ReadyType))
workflowCtx := workflow.NewContext(log, conditions, ctx)
workflowCtx := workflow.NewContext(log, conditions, ctx, bcp)
defer statushandler.Update(workflowCtx, r.Client, r.EventRecorder, bcp)

isValid := customresource.ValidateResourceVersion(workflowCtx, bcp, r.Log)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (r *AtlasCustomRoleReconciler) Reconcile(ctx context.Context, req ctrl.Requ
r.Log.Infow("-> Starting AtlasCustomRole reconciliation", "spec", atlasCustomRole.Spec, "status",
atlasCustomRole.GetStatus())
conditions := akov2.InitCondition(atlasCustomRole, api.FalseCondition(api.ReadyType))
workflowCtx := workflow.NewContext(r.Log, conditions, ctx)
workflowCtx := workflow.NewContext(r.Log, conditions, ctx, atlasCustomRole)
defer func() {
statushandler.Update(workflowCtx, r.Client, r.EventRecorder, atlasCustomRole)
r.Log.Infow("-> Finished AtlasCustomRole reconciliation", "spec", atlasCustomRole.Spec, "status",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,11 @@ func TestAtlasCustomRoleReconciler_Reconcile(t *testing.T) {
return nil, "", fmt.Errorf("failed to create sdk")
}
cdrAPI := mockadmin.NewCustomDatabaseRolesApi(t)
cdrAPI.EXPECT().GetCustomDatabaseRole(context.Background(), "testProjectID", "TestRoleName").
cdrAPI.EXPECT().GetCustomDatabaseRole(mock.Anything, "testProjectID", "TestRoleName").
Return(admin.GetCustomDatabaseRoleApiRequest{ApiService: cdrAPI})
cdrAPI.EXPECT().GetCustomDatabaseRoleExecute(admin.GetCustomDatabaseRoleApiRequest{ApiService: cdrAPI}).
Return(&admin.UserCustomDBRole{}, &http.Response{StatusCode: http.StatusNotFound}, nil)
cdrAPI.EXPECT().CreateCustomDatabaseRole(context.Background(), "testProjectID",
cdrAPI.EXPECT().CreateCustomDatabaseRole(mock.Anything, "testProjectID",
mock.AnythingOfType("*admin.UserCustomDBRole")).
Return(admin.CreateCustomDatabaseRoleApiRequest{ApiService: cdrAPI})
cdrAPI.EXPECT().CreateCustomDatabaseRoleExecute(admin.CreateCustomDatabaseRoleApiRequest{ApiService: cdrAPI}).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (r *AtlasDatabaseUserReconciler) Reconcile(ctx context.Context, req ctrl.Re

r.Log.Infow("-> Starting AtlasDatabaseUser reconciliation", "spec", atlasDatabaseUser.Spec, "status", atlasDatabaseUser.GetStatus())
conditions := akov2.InitCondition(atlasDatabaseUser, api.FalseCondition(api.ReadyType))
workflowCtx := workflow.NewContext(r.Log, conditions, ctx)
workflowCtx := workflow.NewContext(r.Log, conditions, ctx, atlasDatabaseUser)
defer func() {
statushandler.Update(workflowCtx, r.Client, r.EventRecorder, atlasDatabaseUser)
}()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (r *AtlasDataFederationReconciler) Reconcile(context context.Context, req c
}

conditions := akov2.InitCondition(dataFederation, api.FalseCondition(api.ReadyType))
ctx := workflow.NewContext(log, conditions, context)
ctx := workflow.NewContext(log, conditions, context, dataFederation)
log.Infow("-> Starting AtlasDataFederation reconciliation", "spec", dataFederation.Spec, "status", dataFederation.Status)
defer statushandler.Update(ctx, r.Client, r.EventRecorder, dataFederation)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (r *AtlasDeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Requ
}

conditions := akov2.InitCondition(atlasDeployment, api.FalseCondition(api.ReadyType))
workflowCtx := workflow.NewContext(log, conditions, ctx)
workflowCtx := workflow.NewContext(log, conditions, ctx, atlasDeployment)
log.Infow("-> Starting AtlasDeployment reconciliation", "spec", atlasDeployment.Spec, "status", atlasDeployment.Status)
defer func() {
statushandler.Update(workflowCtx, r.Client, r.EventRecorder, atlasDeployment)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ func TestRegularClusterReconciliation(t *testing.T) {
},
SdkClientFunc: func(secretRef *client.ObjectKey, log *zap.SugaredLogger) (*admin.APIClient, string, error) {
clusterAPI := mockadmin.NewClustersApi(t)
clusterAPI.EXPECT().GetCluster(context.Background(), project.ID(), d.GetDeploymentName()).
clusterAPI.EXPECT().GetCluster(mock.Anything, project.ID(), d.GetDeploymentName()).
Return(admin.GetClusterApiRequest{ApiService: clusterAPI})
clusterAPI.EXPECT().GetClusterExecute(mock.AnythingOfType("admin.GetClusterApiRequest")).
Return(
Expand Down Expand Up @@ -423,7 +423,7 @@ func TestRegularClusterReconciliation(t *testing.T) {
&http.Response{},
nil,
)
clusterAPI.EXPECT().GetClusterAdvancedConfiguration(context.Background(), project.ID(), d.GetDeploymentName()).
clusterAPI.EXPECT().GetClusterAdvancedConfiguration(mock.Anything, project.ID(), d.GetDeploymentName()).
Return(admin.GetClusterAdvancedConfigurationApiRequest{ApiService: clusterAPI})
clusterAPI.EXPECT().GetClusterAdvancedConfigurationExecute(mock.AnythingOfType("admin.GetClusterAdvancedConfigurationApiRequest")).
Return(
Expand All @@ -433,7 +433,7 @@ func TestRegularClusterReconciliation(t *testing.T) {
)

searchAPI := mockadmin.NewAtlasSearchApi(t)
searchAPI.EXPECT().GetAtlasSearchDeployment(context.Background(), project.ID(), d.Spec.DeploymentSpec.Name).
searchAPI.EXPECT().GetAtlasSearchDeployment(mock.Anything, project.ID(), d.Spec.DeploymentSpec.Name).
Return(admin.GetAtlasSearchDeploymentApiRequest{ApiService: searchAPI})
searchAPI.EXPECT().GetAtlasSearchDeploymentExecute(mock.Anything).
Return(
Expand All @@ -452,7 +452,7 @@ func TestRegularClusterReconciliation(t *testing.T) {
)

globalAPI := mockadmin.NewGlobalClustersApi(t)
globalAPI.EXPECT().GetManagedNamespace(context.Background(), project.ID(), d.Spec.DeploymentSpec.Name).
globalAPI.EXPECT().GetManagedNamespace(mock.Anything, project.ID(), d.Spec.DeploymentSpec.Name).
Return(admin.GetManagedNamespaceApiRequest{ApiService: globalAPI})
globalAPI.EXPECT().GetManagedNamespaceExecute(mock.Anything).
Return(&admin.GeoSharding{}, nil, nil)
Expand Down Expand Up @@ -615,13 +615,13 @@ func TestServerlessInstanceReconciliation(t *testing.T) {
err := &admin.GenericOpenAPIError{}
err.SetModel(admin.ApiError{ErrorCode: pointer.MakePtr(atlas.ServerlessInstanceFromClusterAPI)})
clusterAPI := mockadmin.NewClustersApi(t)
clusterAPI.EXPECT().GetCluster(context.Background(), project.ID(), d.GetDeploymentName()).
clusterAPI.EXPECT().GetCluster(mock.Anything, project.ID(), d.GetDeploymentName()).
Return(admin.GetClusterApiRequest{ApiService: clusterAPI})
clusterAPI.EXPECT().GetClusterExecute(mock.AnythingOfType("admin.GetClusterApiRequest")).
Return(nil, nil, err)

serverlessAPI := mockadmin.NewServerlessInstancesApi(t)
serverlessAPI.EXPECT().GetServerlessInstance(context.Background(), project.ID(), d.GetDeploymentName()).
serverlessAPI.EXPECT().GetServerlessInstance(mock.Anything, project.ID(), d.GetDeploymentName()).
Return(admin.GetServerlessInstanceApiRequest{ApiService: serverlessAPI})
serverlessAPI.EXPECT().GetServerlessInstanceExecute(mock.AnythingOfType("admin.GetServerlessInstanceApiRequest")).
Return(
Expand All @@ -644,7 +644,7 @@ func TestServerlessInstanceReconciliation(t *testing.T) {
)

speClient := mockadmin.NewServerlessPrivateEndpointsApi(t)
speClient.EXPECT().ListServerlessPrivateEndpoints(context.Background(), project.ID(), d.GetDeploymentName()).
speClient.EXPECT().ListServerlessPrivateEndpoints(mock.Anything, project.ID(), d.GetDeploymentName()).
Return(admin.ListServerlessPrivateEndpointsApiRequest{ApiService: speClient})
speClient.EXPECT().ListServerlessPrivateEndpointsExecute(mock.AnythingOfType("admin.ListServerlessPrivateEndpointsApiRequest")).
Return(nil, &http.Response{}, nil)
Expand Down Expand Up @@ -785,7 +785,7 @@ func TestDeletionReconciliation(t *testing.T) {
},
SdkClientFunc: func(secretRef *client.ObjectKey, log *zap.SugaredLogger) (*admin.APIClient, string, error) {
clusterAPI := mockadmin.NewClustersApi(t)
clusterAPI.EXPECT().GetCluster(context.Background(), project.ID(), d.GetDeploymentName()).
clusterAPI.EXPECT().GetCluster(mock.Anything, project.ID(), d.GetDeploymentName()).
Return(admin.GetClusterApiRequest{ApiService: clusterAPI})
clusterAPI.EXPECT().GetClusterExecute(mock.AnythingOfType("admin.GetClusterApiRequest")).
Return(
Expand Down Expand Up @@ -816,7 +816,7 @@ func TestDeletionReconciliation(t *testing.T) {
&http.Response{},
nil,
)
clusterAPI.EXPECT().DeleteCluster(context.Background(), project.ID(), d.GetDeploymentName()).
clusterAPI.EXPECT().DeleteCluster(mock.Anything, project.ID(), d.GetDeploymentName()).
Return(admin.DeleteClusterApiRequest{ApiService: clusterAPI})
clusterAPI.EXPECT().DeleteClusterExecute(mock.AnythingOfType("admin.DeleteClusterApiRequest")).
Return(&http.Response{}, nil)
Expand Down Expand Up @@ -1163,7 +1163,7 @@ func TestGetProjectFromAtlas(t *testing.T) {
},
SdkClientFunc: func(secretRef *client.ObjectKey, log *zap.SugaredLogger) (*admin.APIClient, string, error) {
projectAPI := mockadmin.NewProjectsApi(t)
projectAPI.EXPECT().GetProject(context.Background(), "project-id").
projectAPI.EXPECT().GetProject(mock.Anything, "project-id").
Return(admin.GetProjectApiRequest{ApiService: projectAPI})
projectAPI.EXPECT().GetProjectExecute(mock.AnythingOfType("admin.GetProjectApiRequest")).
Return(nil, nil, errors.New("failed to get project"))
Expand Down Expand Up @@ -1211,7 +1211,7 @@ func TestGetProjectFromAtlas(t *testing.T) {
},
SdkClientFunc: func(secretRef *client.ObjectKey, log *zap.SugaredLogger) (*admin.APIClient, string, error) {
projectAPI := mockadmin.NewProjectsApi(t)
projectAPI.EXPECT().GetProject(context.Background(), "project-id").
projectAPI.EXPECT().GetProject(mock.Anything, "project-id").
Return(admin.GetProjectApiRequest{ApiService: projectAPI})
projectAPI.EXPECT().GetProjectExecute(mock.AnythingOfType("admin.GetProjectApiRequest")).
Return(&admin.Group{Id: pointer.MakePtr("project-id")}, nil, nil)
Expand Down Expand Up @@ -1557,7 +1557,7 @@ func TestChangeDeploymentType(t *testing.T) {
},
SdkClientFunc: func(secretRef *client.ObjectKey, log *zap.SugaredLogger) (*admin.APIClient, string, error) {
clusterAPI := mockadmin.NewClustersApi(t)
clusterAPI.EXPECT().GetCluster(ctx, "abc123", "cluster0").
clusterAPI.EXPECT().GetCluster(mock.Anything, "abc123", "cluster0").
Return(admin.GetClusterApiRequest{ApiService: clusterAPI})
clusterAPI.EXPECT().GetClusterExecute(mock.AnythingOfType("admin.GetClusterApiRequest")).
RunAndReturn(
Expand All @@ -1573,7 +1573,7 @@ func TestChangeDeploymentType(t *testing.T) {

serverlessAPI := mockadmin.NewServerlessInstancesApi(t)
if !tt.deployment.IsServerless() {
serverlessAPI.EXPECT().GetServerlessInstance(ctx, "abc123", "cluster0").
serverlessAPI.EXPECT().GetServerlessInstance(mock.Anything, "abc123", "cluster0").
Return(admin.GetServerlessInstanceApiRequest{ApiService: serverlessAPI})
serverlessAPI.EXPECT().GetServerlessInstanceExecute(mock.AnythingOfType("admin.GetServerlessInstanceApiRequest")).
Return(&admin.ServerlessInstanceDescription{Name: pointer.MakePtr("cluster0")}, nil, nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (r *AtlasFederatedAuthReconciler) Reconcile(ctx context.Context, req ctrl.R
}

conditions := akov2.InitCondition(fedauth, api.FalseCondition(api.ReadyType))
workflowCtx := workflow.NewContext(log, conditions, ctx)
workflowCtx := workflow.NewContext(log, conditions, ctx, fedauth)
log.Infow("-> Starting AtlasFederatedAuth reconciliation")

defer statushandler.Update(workflowCtx, r.Client, r.EventRecorder, fedauth)
Expand Down
Loading

0 comments on commit 6320166

Please sign in to comment.