Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ GOMOD_LICENSES_SHA := $(shell cat $(LICENSES_GOMOD_SHA_FILE))
OPERATOR_NAMESPACE=atlas-operator
OPERATOR_POD_NAME=mongodb-atlas-operator
RUN_YAML= # Set to the YAML to run when calling make run
RUN_LOG_LEVEL ?= debug

LOCAL_IMAGE=mongodb-atlas-kubernetes-operator:compiled
CONTAINER_SPEC=.spec.template.spec.containers[0]
Expand Down Expand Up @@ -533,7 +534,7 @@ ifdef RUN_YAML
endif
OPERATOR_POD_NAME=$(OPERATOR_POD_NAME) \
OPERATOR_NAMESPACE=$(OPERATOR_NAMESPACE) \
bin/manager --object-deletion-protection=false --log-level=debug \
bin/manager --object-deletion-protection=false --log-level=$(RUN_LOG_LEVEL) \
--atlas-domain=$(ATLAS_DOMAIN) \
--global-api-secret-name=$(ATLAS_KEY_SECRET_NAME)

Expand Down
35 changes: 35 additions & 0 deletions internal/mocks/atlas/integrations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package atlas

import (
"context"

"go.mongodb.org/atlas/mongodbatlas"
)

type IntegrationsMock struct {
CreateFunc func(ctx context.Context, projectID string, integrationType string, integration *mongodbatlas.ThirdPartyIntegration) (*mongodbatlas.ThirdPartyIntegrations, *mongodbatlas.Response, error)
ReplaceFunc func(ctx context.Context, projectID string, integrationType string, integration *mongodbatlas.ThirdPartyIntegration) (*mongodbatlas.ThirdPartyIntegrations, *mongodbatlas.Response, error)
DeleteFunc func(ctx context.Context, projectID string, integrationType string) (*mongodbatlas.Response, error)
GetFunc func(ctx context.Context, projectID string, integrationType string) (*mongodbatlas.ThirdPartyIntegration, *mongodbatlas.Response, error)
ListFunc func(ctx context.Context, projectID string) (*mongodbatlas.ThirdPartyIntegrations, *mongodbatlas.Response, error)
}

func (im *IntegrationsMock) Create(ctx context.Context, projectID string, integrationType string, integration *mongodbatlas.ThirdPartyIntegration) (*mongodbatlas.ThirdPartyIntegrations, *mongodbatlas.Response, error) {
return im.CreateFunc(ctx, projectID, integrationType, integration)
}

func (im *IntegrationsMock) Replace(ctx context.Context, projectID string, integrationType string, integration *mongodbatlas.ThirdPartyIntegration) (*mongodbatlas.ThirdPartyIntegrations, *mongodbatlas.Response, error) {
return im.ReplaceFunc(ctx, projectID, integrationType, integration)
}

func (im *IntegrationsMock) Delete(ctx context.Context, projectID string, integrationType string) (*mongodbatlas.Response, error) {
return im.DeleteFunc(ctx, projectID, integrationType)
}

func (im *IntegrationsMock) Get(ctx context.Context, projectID string, integrationType string) (*mongodbatlas.ThirdPartyIntegration, *mongodbatlas.Response, error) {
return im.GetFunc(ctx, projectID, integrationType)
}

func (im *IntegrationsMock) List(ctx context.Context, projectID string) (*mongodbatlas.ThirdPartyIntegrations, *mongodbatlas.Response, error) {
return im.ListFunc(ctx, projectID)
}
55 changes: 17 additions & 38 deletions pkg/controller/atlasproject/integrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"net/http"
"net/url"
"reflect"

"go.mongodb.org/atlas/mongodbatlas"

Expand Down Expand Up @@ -82,11 +81,11 @@ func (r *AtlasProjectReconciler) updateIntegrationsAtlas(ctx *workflow.Context,
ctx.Log.Warnw("Update Integrations", "Can not convert kube integration", err)
return workflow.Terminate(workflow.ProjectIntegrationInternal, "Update Integrations: Can not convert kube integration")
}
t := mongodbatlas.ThirdPartyIntegration(atlasIntegration)
if &t != kubeIntegration {
specIntegration := (*aliasThirdPartyIntegration)(kubeIntegration)
if !areIntegrationsEqual(specIntegration, &atlasIntegration) {
ctx.Log.Debugf("Try to update integration: %s", kubeIntegration.Type)
if _, _, err := ctx.Client.Integrations.Replace(ctx.Context, projectID, kubeIntegration.Type, kubeIntegration); err != nil {
return workflow.Terminate(workflow.ProjectIntegrationRequest, "Can not convert integration")
return workflow.Terminate(workflow.ProjectIntegrationRequest, fmt.Sprintf("Can not apply integration: %v", err))
}
}
}
Expand Down Expand Up @@ -136,7 +135,7 @@ func (r *AtlasProjectReconciler) checkIntegrationsReady(ctx *workflow.Context, n
} else {
specAsAtlas, _ := spec.ToAtlas(ctx.Context, r.Client, namespace)
specAlias := aliasThirdPartyIntegration(*specAsAtlas)
areEqual = AreIntegrationsEqual(&atlas, &specAlias)
areEqual = integrationsApplied(&atlas, &specAlias)
}
ctx.Log.Debugw("checkIntegrationsReady", "atlas", atlas, "spec", spec, "areEqual", areEqual)

Expand All @@ -148,41 +147,21 @@ func (r *AtlasProjectReconciler) checkIntegrationsReady(ctx *workflow.Context, n
return true
}

func AreIntegrationsEqual(atlas, specAsAtlas *aliasThirdPartyIntegration) bool {
return reflect.DeepEqual(cleanCopyToCompare(atlas), cleanCopyToCompare(specAsAtlas))
}

func cleanCopyToCompare(input *aliasThirdPartyIntegration) *aliasThirdPartyIntegration {
if input == nil {
return input
}

result := *input
keepLastFourChars(&result.APIKey)
keepLastFourChars(&result.APIToken)
keepLastFourChars(&result.LicenseKey)
keepLastFourChars(&result.Password)
keepLastFourChars(&result.ReadToken)
keepLastFourChars(&result.RoutingKey)
keepLastFourChars(&result.Secret)
keepLastFourChars(&result.ServiceKey)
keepLastFourChars(&result.WriteToken)

return &result
func integrationsApplied(_, _ *aliasThirdPartyIntegration) bool {
// As integration secrets are redacted from Alas, we cannot properly compare them,
// so as a simple fix here we assume changes were applied correctly as we would
// have otherwise errored out as are always needed
// TODO: remove and replace calls to this with areIntegrationsEqual when
// that code is properly comparing fields
return true
}

func keepLastFourChars(strPtr *string) {
if strPtr == nil {
return
}

charCount := 4
str := *strPtr
if len(str) <= charCount {
return
}

*strPtr = str[len(str)-charCount:]
func areIntegrationsEqual(_, _ *aliasThirdPartyIntegration) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably a matter of taste but I would extract this into an interface and provide an "AlwaysApplyComparer" or something along these lines. Just to get this stop-the-bleeding patch code out of the sight.

Feel free to ignore this suggestion if you think otherwise.

Copy link
Collaborator Author

@josvazg josvazg Jul 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure is worth it. We are going to actually write quite some new code once we need to actually compare. We just do not know what that code is now, so having interfaces seems premature. For instance, if we go for implicit evaluation these interfaces break, because we need input from 3 sources, Atlas, Spec and annotations.

// As integration secrets are redacted from Alas, we cannot properly compare them,
// so as a simple fix we assume changes are always needed
// TODO: Compare using Atlas redacted fields with checksums if accepted OR
// move to implicit state checks if Atlas cannot help with this.
return false
}

type aliasThirdPartyIntegration mongodbatlas.ThirdPartyIntegration
Expand Down
Loading