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
69 changes: 57 additions & 12 deletions pkg/generate/code/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,44 @@ import (
// constructed from the Read operation, is compared to the Resource we got from
// the Kubernetes API server's event bus. The code that is returned from this
// function is the code that compares those two Resources.
//
// The Go code we return depends on the Go type of the various fields for the
// resource being compared.
//
// For *scalar* Go types, the output Go code looks like this:
//
// if ackcompare.HasNilDifference(a.ko.Spec.GrantFullControl, b.ko.Spec.GrantFullControl) {
// delta.Add("Spec.GrantFullControl", a.ko.Spec.GrantFullControl, b.ko.Spec.GrantFullControl)
// } else if a.ko.Spec.GrantFullControl != nil && b.ko.Spec.GrantFullControl != nil {
// if *a.ko.Spec.GrantFullControl != *b.ko.Spec.GrantFullControl {
// delta.Add("Spec.GrantFullControl", a.ko.Spec.GrantFullControl, b.ko.Spec.GrantFullControl)
// }
// }
//
// For *struct* Go types, the output Go code looks like this (note that it is a
// simple recursive-descent output of all the struct's fields...):
//
// if ackcompare.HasNilDifference(a.ko.Spec.CreateBucketConfiguration, b.ko.Spec.CreateBucketConfiguration) {
// delta.Add("Spec.CreateBucketConfiguration", a.ko.Spec.CreateBucketConfiguration, b.ko.Spec.CreateBucketConfiguration)
// } else if a.ko.Spec.CreateBucketConfiguration != nil && b.ko.Spec.CreateBucketConfiguration != nil {
// if ackcompare.HasNilDifference(a.ko.Spec.CreateBucketConfiguration.LocationConstraint, b.ko.Spec.CreateBucketConfiguration.LocationConstraint) {
// delta.Add("Spec.CreateBucketConfiguration.LocationConstraint", a.ko.Spec.CreateBucketConfiguration.LocationConstraint, b.ko.Spec.CreateBucketConfiguration.LocationConstraint)
// } else if a.ko.Spec.CreateBucketConfiguration.LocationConstraint != nil && b.ko.Spec.CreateBucketConfiguration.LocationConstraint != nil {
// if *a.ko.Spec.CreateBucketConfiguration.LocationConstraint != *b.ko.Spec.CreateBucketConfiguration.LocationConstraint {
// delta.Add("Spec.CreateBucketConfiguration.LocationConstraint", a.ko.Spec.CreateBucketConfiguration.LocationConstraint, b.ko.Spec.CreateBucketConfiguration.LocationConstraint)
// }
// }
// }
//
// For *slice of strings* Go types, the output Go code looks like this:
//
// if ackcompare.HasNilDifference(a.ko.Spec.AllowedPublishers, b.ko.Spec.AllowedPublishers) {
// delta.Add("Spec.AllowedPublishers", a.ko.Spec.AllowedPublishers, b.ko.Spec.AllowedPublishers)
// } else if a.ko.Spec.AllowedPublishers != nil && b.ko.Spec.AllowedPublishers != nil {
// if !ackcompare.SliceStringPEqual(a.ko.Spec.AllowedPublishers.SigningProfileVersionARNs, b.ko.Spec.AllowedPublishers.SigningProfileVersionARNs) {
// delta.Add("Spec.AllowedPublishers.SigningProfileVersionARNs", a.ko.Spec.AllowedPublishers.SigningProfileVersionARNs, b.ko.Spec.AllowedPublishers.SigningProfileVersionARNs)
// }
// }
func CompareResource(
cfg *ackgenconfig.Config,
r *model.CRD,
Expand Down Expand Up @@ -113,8 +151,6 @@ func CompareResource(
nilCode, firstResAdaptedVarName, secondResAdaptedVarName,
)
indentLevel++
} else {
out += "\n"
}

switch memberShape.Type {
Expand Down Expand Up @@ -363,10 +399,15 @@ func compareMap(
indent, firstResVarName, secondResVarName,
)
case "structure":
// TODO(jaypipes): Implement this by walking the keys and struct values
// and comparing each struct individually, building up the fieldPath
// appropriately...
return ""
// NOTE(jaypipes): Using reflect here is really punting. We should
// implement this in a cleaner, more efficient fashion by walking the
// keys and struct values and comparing each struct individually,
// building up the fieldPath appropriately and calling into a
// struct-specific comparator function...
out += fmt.Sprintf(
"%sif !reflect.DeepEqual(%s, %s) {\n",
indent, firstResVarName, secondResVarName,
)
default:
panic("Unsupported shape type in generate.code.compareMap: " + shape.Type)
}
Expand Down Expand Up @@ -431,10 +472,16 @@ func compareSlice(
indent, firstResVarName, secondResVarName,
)
case "structure":
// TODO(jaypipes): Implement this by walking the slice of struct values
// and comparing each struct individually, building up the fieldPath
// appropriately...
return ""
// NOTE(jaypipes): Using reflect here is really punting. We should
// implement this in a cleaner, more efficient fashion by walking the
// struct values and comparing each struct individually, building up
// the fieldPath appropriately and calling into a struct-specific
// comparator function...the tricky part of this is figuring out how to
// sort the slice of structs...
out += fmt.Sprintf(
"%sif !reflect.DeepEqual(%s, %s) {\n",
indent, firstResVarName, secondResVarName,
)
default:
panic("Unsupported shape type in generate.code.compareSlice: " + shape.Type)
}
Expand Down Expand Up @@ -531,8 +578,6 @@ func compareStruct(
nilCode, firstResAdaptedVarName, secondResAdaptedVarName,
)
indentLevel++
} else {
out += "\n"
}
switch memberShape.Type {
case "structure":
Expand Down
5 changes: 3 additions & 2 deletions pkg/generate/code/compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ func TestCompareResource_S3_Bucket(t *testing.T) {
delta.Add("Spec.Logging.LoggingEnabled.TargetBucket", a.ko.Spec.Logging.LoggingEnabled.TargetBucket, b.ko.Spec.Logging.LoggingEnabled.TargetBucket)
}
}

if !reflect.DeepEqual(a.ko.Spec.Logging.LoggingEnabled.TargetGrants, b.ko.Spec.Logging.LoggingEnabled.TargetGrants) {
delta.Add("Spec.Logging.LoggingEnabled.TargetGrants", a.ko.Spec.Logging.LoggingEnabled.TargetGrants, b.ko.Spec.Logging.LoggingEnabled.TargetGrants)
}
if ackcompare.HasNilDifference(a.ko.Spec.Logging.LoggingEnabled.TargetPrefix, b.ko.Spec.Logging.LoggingEnabled.TargetPrefix) {
delta.Add("Spec.Logging.LoggingEnabled.TargetPrefix", a.ko.Spec.Logging.LoggingEnabled.TargetPrefix, b.ko.Spec.Logging.LoggingEnabled.TargetPrefix)
} else if a.ko.Spec.Logging.LoggingEnabled.TargetPrefix != nil && b.ko.Spec.Logging.LoggingEnabled.TargetPrefix != nil {
Expand Down Expand Up @@ -140,7 +142,6 @@ func TestCompareResource_Lambda_CodeSigningConfig(t *testing.T) {
if ackcompare.HasNilDifference(a.ko.Spec.AllowedPublishers, b.ko.Spec.AllowedPublishers) {
delta.Add("Spec.AllowedPublishers", a.ko.Spec.AllowedPublishers, b.ko.Spec.AllowedPublishers)
} else if a.ko.Spec.AllowedPublishers != nil && b.ko.Spec.AllowedPublishers != nil {

if !ackcompare.SliceStringPEqual(a.ko.Spec.AllowedPublishers.SigningProfileVersionARNs, b.ko.Spec.AllowedPublishers.SigningProfileVersionARNs) {
delta.Add("Spec.AllowedPublishers.SigningProfileVersionARNs", a.ko.Spec.AllowedPublishers.SigningProfileVersionARNs, b.ko.Spec.AllowedPublishers.SigningProfileVersionARNs)
}
Expand Down
25 changes: 16 additions & 9 deletions templates/pkg/resource/delta.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,28 @@
package {{ .CRD.Names.Snake }}

import (
"reflect"

ackcompare "github.com/aws-controllers-k8s/runtime/pkg/compare"
)

// Hack to avoid import errors during build...
var (
_ = &reflect.Method{}
)

// newResourceDelta returns a new `ackcompare.Delta` used to compare two
// resources
func newResourceDelta(
a *resource,
b *resource,
a *resource,
b *resource,
) *ackcompare.Delta {
delta := ackcompare.NewDelta()
if ((a == nil && b != nil) ||
(a != nil && b == nil)) {
delta.Add("", a, b)
return delta
}
delta := ackcompare.NewDelta()
if ((a == nil && b != nil) ||
(a != nil && b == nil)) {
delta.Add("", a, b)
return delta
}

{{- if $hookCode := Hook .CRD "delta_pre_compare" }}
{{ $hookCode }}
Expand All @@ -26,5 +33,5 @@ func newResourceDelta(
{{- if $hookCode := Hook .CRD "delta_post_compare" }}
{{ $hookCode }}
{{- end }}
return delta
return delta
}