Skip to content
Open
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
80 changes: 80 additions & 0 deletions pkg/types/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"go/token"
"go/types"
"strings"
"testing"

"github.com/crossplane/crossplane-runtime/v2/pkg/test"
Expand Down Expand Up @@ -219,6 +220,7 @@ func TestBuild(t *testing.T) {
atProvider string
validationRules string
err error
commentChecks map[string]func(t *testing.T, comments map[string]string)
}
cases := map[string]struct {
args
Expand Down Expand Up @@ -637,6 +639,79 @@ func TestBuild(t *testing.T) {
// +kubebuilder:validation:XValidation:rule="!('*' in self.managementPolicies || 'Create' in self.managementPolicies || 'Update' in self.managementPolicies) || has(self.forProvider.__namespace__) || (has(self.initProvider) && has(self.initProvider.__namespace__))",message="spec.forProvider.namespace is a required parameter"`,
},
},
"SSA_InjectedKey_Not_In_Observation_Comments": {
args: args{
crdScope: CRDScopeCluster,
cfg: &config.Resource{
TerraformResource: &schema.Resource{
Schema: map[string]*schema.Schema{
"rule": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"action": {
Type: schema.TypeString,
Required: true,
},
},
},
},
},
},
ServerSideApplyMergeStrategies: config.ServerSideApplyMergeStrategies{
"rule": {
ListMergeStrategy: config.ListMergeStrategy{
MergeStrategy: config.ListTypeMap,
ListMapKeys: config.ListMapKeys{
InjectedKey: config.InjectedKey{
Key: "ruleIndex",
DefaultValue: "0",
},
},
},
},
},
},
},
want: want{
forProvider: `type example.Parameters struct{Rule []example.RuleParameters "json:\"rule,omitempty\" tf:\"rule,omitempty\""}`,
atProvider: `type example.Observation struct{Rule []example.RuleObservation "json:\"rule,omitempty\" tf:\"rule,omitempty\""}`,
commentChecks: map[string]func(t *testing.T, comments map[string]string){
"ParametersRuleHasSSAMarkers": func(t *testing.T, comments map[string]string) {
t.Helper()
v := comments["example.Parameters:Rule"]
if !strings.Contains(v, "+listType=map") {
t.Errorf("Parameters Rule comment missing +listType=map: %s", v)
}
if !strings.Contains(v, "+listMapKey=ruleIndex") {
t.Errorf("Parameters Rule comment missing +listMapKey=ruleIndex: %s", v)
}
},
"ObservationRuleNoSSAMarkers": func(t *testing.T, comments map[string]string) {
t.Helper()
v := comments["example.Observation:Rule"]
if strings.Contains(v, "+listType=map") {
t.Errorf("Observation Rule comment must not contain +listType=map: %s", v)
}
if strings.Contains(v, "+listMapKey") {
t.Errorf("Observation Rule comment must not contain +listMapKey: %s", v)
}
},
"ObservationInjectedKeyNoDefault": func(t *testing.T, comments map[string]string) {
t.Helper()
v := comments["example.RuleObservation:RuleIndex"]
if strings.Contains(v, "+kubebuilder:default") {
t.Errorf("Observation RuleIndex comment must not contain +kubebuilder:default: %s", v)
}
},
},
},
},
}
for n, tc := range cases {
t.Run(n, func(t *testing.T) {
Expand All @@ -659,6 +734,11 @@ func TestBuild(t *testing.T) {
if diff := cmp.Diff(tc.want.validationRules, g.ValidationRules); diff != "" {
t.Fatalf("Build(...): -want validationRules, +got validationRules: %s", diff)
}
for checkName, checkFn := range tc.want.commentChecks {
t.Run(checkName, func(t *testing.T) {
checkFn(t, g.Comments)
})
}
})
}
}
9 changes: 9 additions & 0 deletions pkg/types/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,16 @@ func (f *Field) AddToResource(g *Builder, r *resource, typeNames *TypeNames, opt
// fields under status.atProvider. So, we don't want reference comments to
// be added, hence we are unsetting reference on the field comment just
// before adding it as an observation field.
// Strip listType=map and its associated listMapKey markers from observation
// fields because map-type lists require an injected key with a default value,
// and that default causes conflicts with >1 items sharing a value during
// status updates.
f.Comment.Reference = config.Reference{}
if f.Comment.ServerSideApplyOptions.ListType != nil && *f.Comment.ServerSideApplyOptions.ListType == config.ListTypeMap {
f.Comment.ServerSideApplyOptions.ListType = nil
f.Comment.ServerSideApplyOptions.ListMapKey = nil
}
f.Comment.KubebuilderOptions.Default = nil
g.comments.AddFieldComment(typeNames.ObservationTypeName, f.FieldNameCamel, f.Comment.Build())
}
}
Expand Down
Loading