Skip to content
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

Fix Topic.sns update loops #1347

Merged
merged 2 commits into from
Jun 7, 2024
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
41 changes: 41 additions & 0 deletions config/sns/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ package sns

import (
"github.com/crossplane/upjet/pkg/config"
awspolicy "github.com/hashicorp/awspolicyequivalence"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"

"github.com/upbound/provider-aws/config/common"
)
Expand All @@ -26,5 +30,42 @@ func Configure(p *config.Provider) {
// If the topic policy is unset on the Topic resource, don't late initialize it, to avoid conflicts with the
// policy managed by a TopicPolicy resource.
r.LateInitializer.IgnoredFields = append(r.LateInitializer.IgnoredFields, "policy")
r.TerraformCustomDiff = func(diff *terraform.InstanceDiff, _ *terraform.InstanceState, _ *terraform.ResourceConfig) (*terraform.InstanceDiff, error) {
if diff == nil || diff.Attributes["policy"] == nil || diff.Attributes["policy"].Old == "" || diff.Attributes["policy"].New == "" {
return diff, nil
}

vOld, err := removePolicyVersion(diff.Attributes["policy"].Old)
if err != nil {
return nil, errors.Wrap(err, "failed to remove Version from the old AWS policy document")
}
vNew, err := removePolicyVersion(diff.Attributes["policy"].New)
if err != nil {
return nil, errors.Wrap(err, "failed to remove Version from the new AWS policy document")
}

ok, err := awspolicy.PoliciesAreEquivalent(vOld, vNew)
if err != nil {
return nil, errors.Wrap(err, "failed to compare the old and the new AWS policy documents")
}
if ok {
delete(diff.Attributes, "policy")
}
return diff, nil
}
})
}

func removePolicyVersion(p string) (string, error) {
var policy any
if err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(p), &policy); err != nil {
return "", errors.Wrap(err, "failed to unmarshal the policy from JSON")
}
m, ok := policy.(map[string]any)
if !ok {
return p, nil
}
delete(m, "Version")
r, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(m)
return string(r), errors.Wrap(err, "failed to marshal the policy map as JSON")
}
79 changes: 79 additions & 0 deletions examples/sns/v1beta1/topic-with-policy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# SPDX-FileCopyrightText: 2024 The Crossplane Authors <https://crossplane.io>
#
# SPDX-License-Identifier: CC0-1.0

apiVersion: sns.aws.upbound.io/v1beta1
kind: Topic
metadata:
annotations:
meta.upbound.io/example-id: sns/v1beta1/topic
name: example-topic-${Rand.RFC1123Subdomain}
labels:
testing.upbound.io/example-name: sns
spec:
forProvider:
region: us-west-1
policy: |-
{
"Statement": [
{
"Sid": "publish",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::153891904029:role/sample-role"
]
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-west-1:123456789110:resource1"
},
{
"Sid": "get-attributes",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::153891904029:role/sample-role"
]
},
"Action": "sns:GetTopicAttributes",
"Resource": "arn:aws:sns:us-west-1:123456789110:resource1"
},
{
"Sid": "list-subscriptions",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::153891904029:role/sample-role"
]
},
"Action": "sns:ListSubscriptionsByTopic",
"Resource": "arn:aws:sns:us-west-1:123456789110:resource1"
}
]
}

---

apiVersion: iam.aws.upbound.io/v1beta1
kind: Role
metadata:
annotations:
meta.upbound.io/example-id: sns/v1beta1/topic
labels:
testing.upbound.io/example-name: role
name: sample-role
spec:
forProvider:
assumeRolePolicy: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ require (
github.com/crossplane/upjet v1.4.1
github.com/go-ini/ini v1.46.0
github.com/google/go-cmp v0.6.0
github.com/hashicorp/awspolicyequivalence v1.6.0
github.com/hashicorp/terraform-json v0.21.0
github.com/hashicorp/terraform-plugin-framework v1.8.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0
github.com/hashicorp/terraform-provider-aws v0.0.0-00010101000000-000000000000
github.com/json-iterator/go v1.1.12
github.com/pkg/errors v0.9.1
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/yaml.v3 v3.0.1
Expand Down Expand Up @@ -259,7 +261,6 @@ require (
github.com/hashicorp/aws-cloudformation-resource-schema-sdk-go v0.22.0 // indirect
github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.53 // indirect
github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2 v2.0.0-beta.54 // indirect
github.com/hashicorp/awspolicyequivalence v1.6.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
Expand Down Expand Up @@ -289,7 +290,6 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattbaird/jsonpatch v0.0.0-20230413205102-771768614e91 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
Expand Down
Loading