From 2c8efc7d16cc4e3d7570f23ff358a046b723ad03 Mon Sep 17 00:00:00 2001 From: Stephane Selim Date: Mon, 12 Aug 2024 18:44:02 +0200 Subject: [PATCH] implement tests for resource policy custom methods Signed-off-by: Stephane Selim --- .../cloudwatchlogs/resourcepolicy/setup.go | 22 +- .../resourcepolicy/setup_test.go | 391 ++++++++++++++++++ 2 files changed, 409 insertions(+), 4 deletions(-) create mode 100644 pkg/controller/cloudwatchlogs/resourcepolicy/setup_test.go diff --git a/pkg/controller/cloudwatchlogs/resourcepolicy/setup.go b/pkg/controller/cloudwatchlogs/resourcepolicy/setup.go index bf479d7e99..0979987720 100644 --- a/pkg/controller/cloudwatchlogs/resourcepolicy/setup.go +++ b/pkg/controller/cloudwatchlogs/resourcepolicy/setup.go @@ -80,10 +80,15 @@ func postObserve(_ context.Context, cr *svcapitypes.ResourcePolicy, _ *svcsdk.De } func isUpToDate(_ context.Context, cr *svcapitypes.ResourcePolicy, obj *svcsdk.DescribeResourcePoliciesOutput) (bool, string, error) { - if len(obj.ResourcePolicies) == 0 { + if obj == nil || len(obj.ResourcePolicies) == 0 { return false, "", nil } + if cr == nil || cr.Spec.ForProvider.PolicyDocument == nil { + return false, "", nil + } + + // Check if the policy exists for _, policy := range obj.ResourcePolicies { if policy.PolicyName != nil && *policy.PolicyName == meta.GetExternalName(cr) { // Use existing method from iam to compare policy documents @@ -93,11 +98,20 @@ func isUpToDate(_ context.Context, cr *svcapitypes.ResourcePolicy, obj *svcsdk.D return false, "", nil } -func filterList(cr *svcapitypes.ResourcePolicy, list *svcsdk.DescribeResourcePoliciesOutput) *svcsdk.DescribeResourcePoliciesOutput { +func filterList(cr *svcapitypes.ResourcePolicy, obj *svcsdk.DescribeResourcePoliciesOutput) *svcsdk.DescribeResourcePoliciesOutput { resp := &svcsdk.DescribeResourcePoliciesOutput{} + if obj == nil || len(obj.ResourcePolicies) == 0 { + return resp + } + + if cr == nil { + return resp + } + + resourcePolicyIdentifier := pointer.ToOrNilIfZeroValue(meta.GetExternalName(cr)) - for _, resourcePolicy := range list.ResourcePolicies { - if pointer.StringValue(resourcePolicy.PolicyName) == meta.GetExternalName(cr) { + for _, resourcePolicy := range obj.ResourcePolicies { + if pointer.StringValue(resourcePolicy.PolicyName) == pointer.StringValue(resourcePolicyIdentifier) { resp.ResourcePolicies = append(resp.ResourcePolicies, resourcePolicy) break } diff --git a/pkg/controller/cloudwatchlogs/resourcepolicy/setup_test.go b/pkg/controller/cloudwatchlogs/resourcepolicy/setup_test.go new file mode 100644 index 0000000000..c0d399b509 --- /dev/null +++ b/pkg/controller/cloudwatchlogs/resourcepolicy/setup_test.go @@ -0,0 +1,391 @@ +/* +Copyright 2019 The Crossplane Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resourcepolicy + +import ( + "context" + "github.com/crossplane/crossplane-runtime/pkg/meta" + "github.com/crossplane/crossplane-runtime/pkg/test" + "github.com/google/go-cmp/cmp" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "testing" + + "github.com/aws/aws-sdk-go/aws" + svcsdk "github.com/aws/aws-sdk-go/service/cloudwatchlogs" + svcapitypes "github.com/crossplane-contrib/provider-aws/apis/cloudwatchlogs/v1alpha1" +) + +const ( + testPolicyDocument = `{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Route53LogsToCloudWatchLogs", + "Effect": "Allow", + "Principal": { + "Service": "route53.amazonaws.com" + }, + "Action": "logs:PutLogEvents", + "Resource": "logArn" + } + ] + }` + testPolicyDocument2 = `{ + "Version" : "2012-10-17", + "Statement" : [ + { + "Sid" : "", + "Effect" : "Allow", + "Principal" : { + "Service" : "111122223333" + }, + "Action" : "logs:PutSubscriptionFilter", + "Resource" : "arn:aws:logs:us-east-1:123456789012:destination:testDestination" + } + ] + }` + policyName = "policyName" + otherPolicyName = "otherPolicyName" +) + +type args struct { + describeResourcePoliciesOutput *svcsdk.DescribeResourcePoliciesOutput + resourcePolicy *svcapitypes.ResourcePolicy +} + +func TestIsUpToDate(t *testing.T) { + type want struct { + result bool + diff string + err error + } + + cases := map[string]struct { + args args + want want + }{ + "SameFields": { + args: args{ + describeResourcePoliciesOutput: &svcsdk.DescribeResourcePoliciesOutput{ + ResourcePolicies: []*svcsdk.ResourcePolicy{ + { + PolicyName: aws.String(policyName), + PolicyDocument: aws.String(testPolicyDocument), + }, + { + PolicyName: aws.String(otherPolicyName), + PolicyDocument: aws.String(testPolicyDocument2), + }, + }, + }, + resourcePolicy: &svcapitypes.ResourcePolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: policyName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: policyName, + }, + }, + Spec: svcapitypes.ResourcePolicySpec{ + ForProvider: svcapitypes.ResourcePolicyParameters{ + PolicyDocument: aws.String(testPolicyDocument), + }, + }, + }, + }, + want: want{ + result: true, + err: nil, + }, + }, + "DifferentPolicyDocument": { + args: args{ + describeResourcePoliciesOutput: &svcsdk.DescribeResourcePoliciesOutput{ + ResourcePolicies: []*svcsdk.ResourcePolicy{ + { + PolicyName: aws.String(policyName), + PolicyDocument: aws.String(testPolicyDocument), + }, + }, + }, + resourcePolicy: &svcapitypes.ResourcePolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: policyName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: policyName, + }, + }, + Spec: svcapitypes.ResourcePolicySpec{ + ForProvider: svcapitypes.ResourcePolicyParameters{ + PolicyDocument: aws.String(testPolicyDocument2), + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "ResourcePolicyNotFound": { + args: args{ + describeResourcePoliciesOutput: &svcsdk.DescribeResourcePoliciesOutput{ + ResourcePolicies: []*svcsdk.ResourcePolicy{ + { + PolicyName: aws.String(otherPolicyName), + PolicyDocument: aws.String(testPolicyDocument2), + }, + }, + }, + resourcePolicy: &svcapitypes.ResourcePolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: policyName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: policyName, + }, + }, + Spec: svcapitypes.ResourcePolicySpec{ + ForProvider: svcapitypes.ResourcePolicyParameters{ + PolicyDocument: aws.String(testPolicyDocument), + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "ResourcePolicyNotFoundEmptyDescribeResourcePoliciesOutput": { + args: args{ + describeResourcePoliciesOutput: &svcsdk.DescribeResourcePoliciesOutput{ + ResourcePolicies: []*svcsdk.ResourcePolicy{}, + }, + resourcePolicy: &svcapitypes.ResourcePolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: policyName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: policyName, + }, + }, + Spec: svcapitypes.ResourcePolicySpec{ + ForProvider: svcapitypes.ResourcePolicyParameters{ + PolicyDocument: aws.String(testPolicyDocument), + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "ResourcePolicyNotFoundNilDescribeResourcePoliciesOutput": { + args: args{ + describeResourcePoliciesOutput: nil, + resourcePolicy: &svcapitypes.ResourcePolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: policyName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: policyName, + }, + }, + Spec: svcapitypes.ResourcePolicySpec{ + ForProvider: svcapitypes.ResourcePolicyParameters{ + PolicyDocument: aws.String(testPolicyDocument), + }, + }, + }, + }, + want: want{ + result: false, + err: nil, + }, + }, + "ResourcePolicyNotFoundNilResourcePolicy": { + args: args{ + describeResourcePoliciesOutput: &svcsdk.DescribeResourcePoliciesOutput{ + ResourcePolicies: []*svcsdk.ResourcePolicy{ + { + PolicyName: aws.String(policyName), + PolicyDocument: aws.String(testPolicyDocument), + }, + }, + }, + resourcePolicy: nil, + }, + want: want{ + result: false, + err: nil, + }, + }, + "ResourcePolicyNotFoundNilResourcePolicyAndDescribeResourcePoliciesOutput": { + args: args{ + describeResourcePoliciesOutput: nil, + resourcePolicy: nil, + }, + want: want{ + result: false, + err: nil, + }, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + + got, _, err := isUpToDate(context.Background(), tc.args.resourcePolicy, tc.args.describeResourcePoliciesOutput) + + if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { + t.Errorf("isUpToDate(...): -want error, +got error: %s", diff) + } + if diff := cmp.Diff(tc.want.result, got); diff != "" { + t.Errorf("isUpToDate(...): -want, +got: %s", diff) + } + }) + } +} + +func TestFilterList(t *testing.T) { + type want struct { + resp *svcsdk.DescribeResourcePoliciesOutput + } + cases := map[string]struct { + args args + want want + }{ + "ResourcePolicyFound": { + args: args{ + describeResourcePoliciesOutput: &svcsdk.DescribeResourcePoliciesOutput{ + ResourcePolicies: []*svcsdk.ResourcePolicy{ + { + PolicyName: aws.String(policyName), + }, + { + PolicyName: aws.String(otherPolicyName), + }, + }, + }, + resourcePolicy: &svcapitypes.ResourcePolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: policyName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: policyName, + }, + }, + }, + }, + want: want{ + resp: &svcsdk.DescribeResourcePoliciesOutput{ + ResourcePolicies: []*svcsdk.ResourcePolicy{ + { + PolicyName: aws.String(policyName), + }, + }, + }, + }, + }, + "ResourcePolicyNotFound": { + args: args{ + describeResourcePoliciesOutput: &svcsdk.DescribeResourcePoliciesOutput{ + ResourcePolicies: []*svcsdk.ResourcePolicy{ + { + PolicyName: aws.String(otherPolicyName), + }, + }, + }, + resourcePolicy: &svcapitypes.ResourcePolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: policyName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: policyName, + }, + }, + }, + }, + want: want{ + resp: &svcsdk.DescribeResourcePoliciesOutput{}, + }, + }, + "ResourcePolicyNotFoundEmptyDescribeResourcePoliciesOutput": { + args: args{ + describeResourcePoliciesOutput: &svcsdk.DescribeResourcePoliciesOutput{ + ResourcePolicies: []*svcsdk.ResourcePolicy{}, + }, + resourcePolicy: &svcapitypes.ResourcePolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: policyName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: policyName, + }, + }, + }, + }, + want: want{ + resp: &svcsdk.DescribeResourcePoliciesOutput{}, + }, + }, + "ResourcePolicyNotFoundNilDescribeResourcePoliciesOutput": { + args: args{ + describeResourcePoliciesOutput: nil, + resourcePolicy: &svcapitypes.ResourcePolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: policyName, + Annotations: map[string]string{ + meta.AnnotationKeyExternalName: policyName, + }, + }, + }, + }, + want: want{ + resp: &svcsdk.DescribeResourcePoliciesOutput{}, + }, + }, + "ResourcePolicyNotFoundNilResourcePolicy": { + args: args{ + describeResourcePoliciesOutput: &svcsdk.DescribeResourcePoliciesOutput{ + ResourcePolicies: []*svcsdk.ResourcePolicy{ + { + PolicyName: aws.String(policyName), + }, + }, + }, + resourcePolicy: nil, + }, + want: want{ + resp: &svcsdk.DescribeResourcePoliciesOutput{}, + }, + }, + "ResourcePolicyNotFoundNilResourcePolicyAndDescribeResourcePoliciesOutput": { + args: args{ + describeResourcePoliciesOutput: nil, + resourcePolicy: nil, + }, + want: want{ + resp: &svcsdk.DescribeResourcePoliciesOutput{}, + }, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + resp := filterList(tc.args.resourcePolicy, tc.args.describeResourcePoliciesOutput) + if diff := cmp.Diff(tc.want.resp, resp); diff != "" { + t.Errorf("filterList(...): -want, +got: %s", diff) + } + }) + } +}