Skip to content

Commit

Permalink
Merge pull request #1687 from crossplane-contrib/backport-1672-to-rel…
Browse files Browse the repository at this point in the history
…ease-1.20

[Backport release-1.20] Add Update Prevent function to `mq_configuraiton` resource for preventing the update loop
  • Loading branch information
sergenyalcin authored Feb 13, 2025
2 parents a6c7438 + aa5ea31 commit d83ef90
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 4 deletions.
67 changes: 67 additions & 0 deletions config/mq/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
package mq

import (
"encoding/base64"
"fmt"

"github.com/crossplane/crossplane-runtime/pkg/errors"
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
xpresource "github.com/crossplane/crossplane-runtime/pkg/resource"
"github.com/crossplane/upjet/pkg/config"
"github.com/crossplane/upjet/pkg/registry"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

// Configure adds configurations for the mq group.
Expand Down Expand Up @@ -74,4 +79,66 @@ func Configure(p *config.Provider) { //nolint:gocyclo
}
r.MetaResource.ArgumentDocs["console_access"] = `- (Optional) Setting consoleAccess will result in an update loop till the MQ Broker to which this user belongs is restarted.`
})

p.AddResourceConfigurator("aws_mq_configuration", func(r *config.Resource) {
c := &repeatedDiffCheckerForData{}
r.UpdateLoopPrevention = c
})
}

// repeatedDiffCheckerForData implements the UpdateLoopPrevention interface.
// It is responsible for checking if the same diff related to the "data"
// argument (in this case, XML content) appears repeatedly, which may indicate
// a schema violation or invalid data scenario. If a repeated diff is detected,
// it blocks the update process.
type repeatedDiffCheckerForData struct {
// previousDiff stores the base64-encoded string of the last diff.
// This is used to compare against the current diff to detect repeated
// updates.
previousDiff *string
}

// UpdateLoopPreventionFunc checks for repeated diffs in the resource's "data"
// attribute. If the diff has not changed since the previous reconciliation
// loop, it blocks the update by returning an appropriate result.
func (c *repeatedDiffCheckerForData) UpdateLoopPreventionFunc(diff *terraform.InstanceDiff, mg xpresource.Managed) (*config.UpdateLoopPreventResult, error) { //nolint:gocyclo // easier to follow as a unit
// Skip processing if there is no diff, the diff is empty, or it is a destroy operation.
if diff == nil || diff.Empty() || diff.Destroy || diff.Attributes == nil {
return nil, nil
}
paved, err := fieldpath.PaveObject(mg)
if err != nil {
return nil, errors.Wrap(err, "cannot pave object")
}
// Retrieve the value of the "spec.forProvider.engineType" field from the paved object.
// This field is used to determine the engine type of the MQ configuration.
engineType, err := paved.GetString("spec.forProvider.engineType")
if err != nil {
return nil, errors.Wrap(err, "cannot get value of spec.forProvider.engineType")
}
// Check if the engine type is "ActiveMQ". If it is not, skip further checks and return nil.
// This block ensures that the diff check logic only applies to resources with ActiveMQ engine type,
// avoiding unnecessary diff processing for other engine types.
if engineType != "ActiveMQ" {
return nil, nil
}
// Encode the "data" attribute of the diff into a base64 string for comparison.
var encodedDiff string
if dataDiff, ok := diff.Attributes["data"]; ok {
// Use GoString to get a string representation of the attribute.
encodedDiff = base64.StdEncoding.EncodeToString([]byte(dataDiff.GoString()))
}
// If there is no previous diff recorded, store the current diff and allow the update to proceed.
if c.previousDiff == nil {
c.previousDiff = &encodedDiff
return nil, nil
}
// If the current diff matches the previous diff, block the update and return a reason.
if encodedDiff == *c.previousDiff {
return &config.UpdateLoopPreventResult{Reason: "Repeated diff for the provided XML data, please check the XML content you have provided. " +
"It may contain invalid or schema violating content."}, nil
}
// Update the previous diff with the current diff for the next reconciliation loop.
c.previousDiff = &encodedDiff
return nil, nil
}
2 changes: 1 addition & 1 deletion examples/mq/v1beta1/configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ spec:
</broker>
description: Example Configuration
engineType: ActiveMQ
engineVersion: 5.15.0
engineVersion: "5.18"
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
github.com/aws/smithy-go v1.22.1
github.com/crossplane/crossplane-runtime v1.17.0
github.com/crossplane/crossplane-tools v0.0.0-20230925130601-628280f8bf79
github.com/crossplane/upjet v1.4.1-0.20250206162150-1a6d69bbd22a
github.com/crossplane/upjet v1.5.0
github.com/go-ini/ini v1.46.0
github.com/google/go-cmp v0.6.0
github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.59
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -580,8 +580,8 @@ github.com/crossplane/crossplane-runtime v1.17.0 h1:y+GvxPT1M9s8BKt2AeZJdd2d6pg2
github.com/crossplane/crossplane-runtime v1.17.0/go.mod h1:vtglCrnnbq2HurAk9yLHa4qS0bbnCxaKL7C21cQcB/0=
github.com/crossplane/crossplane-tools v0.0.0-20230925130601-628280f8bf79 h1:HigXs5tEQxWz0fcj8hzbU2UAZgEM7wPe0XRFOsrtF8Y=
github.com/crossplane/crossplane-tools v0.0.0-20230925130601-628280f8bf79/go.mod h1:+e4OaFlOcmr0JvINHl/yvEYBrZawzTgj6pQumOH1SS0=
github.com/crossplane/upjet v1.4.1-0.20250206162150-1a6d69bbd22a h1:BX1cOu+WEPMWG9/qI9B4gjOMYFC82L+40PJ+7wuW94s=
github.com/crossplane/upjet v1.4.1-0.20250206162150-1a6d69bbd22a/go.mod h1:F2u9XwKNzxM+myfS1Opjnc6a5E1N2PC7Mytbkavawvs=
github.com/crossplane/upjet v1.5.0 h1:SJc6lUKjcuIGrJmu4dXgnS6OlP1/xBasHhGk4uAW1yI=
github.com/crossplane/upjet v1.5.0/go.mod h1:F2u9XwKNzxM+myfS1Opjnc6a5E1N2PC7Mytbkavawvs=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/dave/jennifer v1.4.1 h1:XyqG6cn5RQsTj3qlWQTKlRGAyrTcsk1kUmWdZBzRjDw=
Expand Down

0 comments on commit d83ef90

Please sign in to comment.