@@ -15,8 +15,10 @@ package table
1515
1616import  (
1717	"context" 
18+ 	"encoding/json" 
1819	"errors" 
1920	"fmt" 
21+ 	"reflect" 
2022	"strings" 
2123	"time" 
2224
@@ -28,6 +30,7 @@ import (
2830	"github.com/aws/aws-sdk-go-v2/aws" 
2931	svcsdk "github.com/aws/aws-sdk-go-v2/service/dynamodb" 
3032	svcsdktypes "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" 
33+ 	awsiampolicy "github.com/micahhausler/aws-iam-policy/policy" 
3134	corev1 "k8s.io/api/core/v1" 
3235
3336	"github.com/aws-controllers-k8s/dynamodb-controller/apis/v1alpha1" 
@@ -694,14 +697,7 @@ func customPreCompare(
694697			delta .Add ("Spec.ContributorInsights" , a .ko .Spec .ContributorInsights , b .ko .Spec .ContributorInsights )
695698		}
696699	}
697- 
698- 	if  ackcompare .HasNilDifference (a .ko .Spec .ResourcePolicy , b .ko .Spec .ResourcePolicy ) {
699- 		delta .Add ("Spec.ResourcePolicy" , a .ko .Spec .ResourcePolicy , b .ko .Spec .ResourcePolicy )
700- 	} else  if  a .ko .Spec .ResourcePolicy  !=  nil  &&  b .ko .Spec .ResourcePolicy  !=  nil  {
701- 		if  * a .ko .Spec .ResourcePolicy  !=  * b .ko .Spec .ResourcePolicy  {
702- 			delta .Add ("Spec.ResourcePolicy" , a .ko .Spec .ResourcePolicy , b .ko .Spec .ResourcePolicy )
703- 		}
704- 	}
700+ 	compareResourcePolicyDocument (delta , a , b )
705701
706702}
707703
@@ -917,3 +913,43 @@ func (rm *resourceManager) updateContributorInsights(
917913
918914	return  nil 
919915}
916+ 
917+ // compareResourcePolicyDocument is a custom comparison function for 
918+ // ResourcePolicy documents. The reason why we need a custom function for 
919+ // this field is to handle the variability in shapes of JSON objects representing 
920+ // IAM policies, especially when it comes to statements, actions, and other fields. 
921+ func  compareResourcePolicyDocument (
922+ 	delta  * ackcompare.Delta ,
923+ 	a  * resource ,
924+ 	b  * resource ,
925+ ) {
926+ 	// Handle cases where one policy is nil and the other is not. 
927+ 	// This means one resource has a policy and the other doesn't - they're different. 
928+ 	if  ackcompare .HasNilDifference (a .ko .Spec .ResourcePolicy , b .ko .Spec .ResourcePolicy ) {
929+ 		delta .Add ("Spec.ResourcePolicy" , a .ko .Spec .ResourcePolicy , b .ko .Spec .ResourcePolicy )
930+ 		return 
931+ 	}
932+ 
933+ 	// If both policies are nil, there's no difference - both resources have no policy. 
934+ 	if  a .ko .Spec .ResourcePolicy  ==  nil  &&  b .ko .Spec .ResourcePolicy  ==  nil  {
935+ 		return 
936+ 	}
937+ 
938+ 	// At this point, both policies are non-nil. We need to compare their JSON content. 
939+ 	// To handle the variability in shapes of JSON objects representing IAM policies, 
940+ 	// especially when it comes to statements, actions, and other fields, we need 
941+ 	// a custom json.Unmarshaller approach crafted to our specific needs. Luckily, 
942+ 	// it happens that @micahhausler built a library dedicated to this very special 
943+ 	// need: github.com/micahhausler/aws-iam-policy. 
944+ 	// 
945+ 	// Copied from IAM Controller: https://github.com/aws-controllers-k8s/iam-controller/blob/main/pkg/resource/role/hooks.go#L398-L432 
946+ 	// Based on review feedback: https://github.com/aws-controllers-k8s/dynamodb-controller/pull/154#discussion_r2443876840 
947+ 	var  policyDocumentA  awsiampolicy.Policy 
948+ 	_  =  json .Unmarshal ([]byte (* a .ko .Spec .ResourcePolicy ), & policyDocumentA )
949+ 	var  policyDocumentB  awsiampolicy.Policy 
950+ 	_  =  json .Unmarshal ([]byte (* b .ko .Spec .ResourcePolicy ), & policyDocumentB )
951+ 
952+ 	if  ! reflect .DeepEqual (policyDocumentA , policyDocumentB ) {
953+ 		delta .Add ("Spec.ResourcePolicy" , a .ko .Spec .ResourcePolicy , b .ko .Spec .ResourcePolicy )
954+ 	}
955+ }
0 commit comments