From ce46d387cb2cda68ae6d1c6627f2ecb50818ac96 Mon Sep 17 00:00:00 2001 From: Hasan Turken Date: Fri, 24 Feb 2023 15:10:00 +0300 Subject: [PATCH 1/3] Include full state under status.atProvider Signed-off-by: Hasan Turken --- pkg/types/builder.go | 6 ++++++ pkg/types/builder_test.go | 8 ++++---- pkg/types/field.go | 18 ++++++++++++++---- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/pkg/types/builder.go b/pkg/types/builder.go index fa7b1a39..a830a5bd 100644 --- a/pkg/types/builder.go +++ b/pkg/types/builder.go @@ -277,6 +277,12 @@ func (r *resource) addParameterField(f *Field, field *types.Var) { } func (r *resource) addObservationField(f *Field, field *types.Var) { + for _, obsF := range r.obsFields { + if obsF.Name() == field.Name() { + // If the field is already added, we don't add it again. + return + } + } r.obsFields = append(r.obsFields, field) r.obsTags = append(r.obsTags, fmt.Sprintf(`json:"%s" tf:"%s"`, f.JSONTag, f.TFTag)) } diff --git a/pkg/types/builder_test.go b/pkg/types/builder_test.go index 2c29e570..7c1be8c1 100644 --- a/pkg/types/builder_test.go +++ b/pkg/types/builder_test.go @@ -250,7 +250,7 @@ func TestBuild(t *testing.T) { }, want: want{ forProvider: `type example.Parameters struct{Enable *bool "json:\"enable,omitempty\" tf:\"enable,omitempty\""; ID *int64 "json:\"id\" tf:\"id,omitempty\""; Name *string "json:\"name\" tf:\"name,omitempty\""}`, - atProvider: `type example.Observation struct{Config *string "json:\"config,omitempty\" tf:\"config,omitempty\""; Value *float64 "json:\"value,omitempty\" tf:\"value,omitempty\""}`, + atProvider: `type example.Observation struct{Config *string "json:\"config,omitempty\" tf:\"config,omitempty\""; Enable *bool "json:\"enable,omitempty\" tf:\"enable,omitempty\""; ID *int64 "json:\"id,omitempty\" tf:\"id,omitempty\""; Name *string "json:\"name,omitempty\" tf:\"name,omitempty\""; Value *float64 "json:\"value,omitempty\" tf:\"value,omitempty\""}`, }, }, "Resource_Types": { @@ -283,7 +283,7 @@ func TestBuild(t *testing.T) { }, want: want{ forProvider: `type example.Parameters struct{List []*string "json:\"list\" tf:\"list,omitempty\""; ResourceIn map[string]example.ResourceInParameters "json:\"resourceIn\" tf:\"resource_in,omitempty\""}`, - atProvider: `type example.Observation struct{ResourceOut map[string]example.ResourceOutObservation "json:\"resourceOut,omitempty\" tf:\"resource_out,omitempty\""}`, + atProvider: `type example.Observation struct{List []*string "json:\"list,omitempty\" tf:\"list,omitempty\""; ResourceIn map[string]example.ResourceInParameters "json:\"resourceIn,omitempty\" tf:\"resource_in,omitempty\""; ResourceOut map[string]example.ResourceOutObservation "json:\"resourceOut,omitempty\" tf:\"resource_out,omitempty\""}`, }, }, "Sensitive_Fields": { @@ -310,7 +310,7 @@ func TestBuild(t *testing.T) { }, want: want{ forProvider: `type example.Parameters struct{Key1SecretRef *github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key1SecretRef,omitempty\" tf:\"-\""; Key2SecretRef github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key2SecretRef\" tf:\"-\""; Key3SecretRef []github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key3SecretRef\" tf:\"-\""}`, - atProvider: `type example.Observation struct{}`, + atProvider: `type example.Observation struct{Key1SecretRef *github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key1SecretRef,omitempty\" tf:\"-\""; Key2SecretRef github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key2SecretRef\" tf:\"-\""; Key3SecretRef []github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key3SecretRef\" tf:\"-\""}`, }, }, "Invalid_Sensitive_Fields": { @@ -355,7 +355,7 @@ func TestBuild(t *testing.T) { }, want: want{ forProvider: `type example.Parameters struct{Name *string "json:\"name\" tf:\"name,omitempty\""; ReferenceID *string "json:\"referenceId,omitempty\" tf:\"reference_id,omitempty\""; ExternalResourceID *github.com/crossplane/crossplane-runtime/apis/common/v1.Reference "json:\"externalResourceId,omitempty\" tf:\"-\""; ReferenceIDSelector *github.com/crossplane/crossplane-runtime/apis/common/v1.Selector "json:\"referenceIdSelector,omitempty\" tf:\"-\""}`, - atProvider: `type example.Observation struct{}`, + atProvider: `type example.Observation struct{Name *string "json:\"name,omitempty\" tf:\"name,omitempty\""; ReferenceID *string "json:\"referenceId,omitempty\" tf:\"reference_id,omitempty\""}`, }, }, "Invalid_Schema_Type": { diff --git a/pkg/types/field.go b/pkg/types/field.go index 6c094544..647220e2 100644 --- a/pkg/types/field.go +++ b/pkg/types/field.go @@ -204,10 +204,12 @@ func (f *Field) AddToResource(g *Builder, r *resource, typeNames *TypeNames) { } field := types.NewField(token.NoPos, g.Package, f.FieldNameCamel, f.FieldType, false) - switch { - case IsObservation(f.Schema): - r.addObservationField(f, field) - default: + + // Note(turkenh): We want atProvider to be a superset of forProvider, so + // we always add the field as an observation field and then add it as a + // parameter field if it's not an observation (only) field, i.e. parameter. + r.addObservationField(f, field) + if !IsObservation(f.Schema) { if f.AsBlocksMode { f.TFTag = strings.TrimSuffix(f.TFTag, ",omitempty") } @@ -219,6 +221,14 @@ func (f *Field) AddToResource(g *Builder, r *resource, typeNames *TypeNames) { } g.comments.AddFieldComment(typeNames.ParameterTypeName, f.FieldNameCamel, f.Comment.Build()) + // Note(turkenh): We don't want reference resolver to be generated for + // 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. + f.Comment.Reference = config.Reference{} + // Note(turkenh): We don't need required/optional markers for observation + // fields. + f.Comment.Required = nil g.comments.AddFieldComment(typeNames.ObservationTypeName, f.FieldNameCamel, f.Comment.Build()) } From a0306ce5fd02ca4c8f1c6f1c16580de98dc79f77 Mon Sep 17 00:00:00 2001 From: Hasan Turken Date: Wed, 5 Apr 2023 17:20:38 +0300 Subject: [PATCH 2/3] Do not add fields with no tag to status Signed-off-by: Hasan Turken --- pkg/types/builder_test.go | 2 +- pkg/types/field.go | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pkg/types/builder_test.go b/pkg/types/builder_test.go index 7c1be8c1..75486197 100644 --- a/pkg/types/builder_test.go +++ b/pkg/types/builder_test.go @@ -310,7 +310,7 @@ func TestBuild(t *testing.T) { }, want: want{ forProvider: `type example.Parameters struct{Key1SecretRef *github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key1SecretRef,omitempty\" tf:\"-\""; Key2SecretRef github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key2SecretRef\" tf:\"-\""; Key3SecretRef []github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key3SecretRef\" tf:\"-\""}`, - atProvider: `type example.Observation struct{Key1SecretRef *github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key1SecretRef,omitempty\" tf:\"-\""; Key2SecretRef github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key2SecretRef\" tf:\"-\""; Key3SecretRef []github.com/crossplane/crossplane-runtime/apis/common/v1.SecretKeySelector "json:\"key3SecretRef\" tf:\"-\""}`, + atProvider: `type example.Observation struct{}`, }, }, "Invalid_Sensitive_Fields": { diff --git a/pkg/types/field.go b/pkg/types/field.go index 647220e2..28551f1b 100644 --- a/pkg/types/field.go +++ b/pkg/types/field.go @@ -208,7 +208,13 @@ func (f *Field) AddToResource(g *Builder, r *resource, typeNames *TypeNames) { // Note(turkenh): We want atProvider to be a superset of forProvider, so // we always add the field as an observation field and then add it as a // parameter field if it's not an observation (only) field, i.e. parameter. - r.addObservationField(f, field) + // + // We do this only if tf tag is not set to "-" because otherwise it won't + // be populated from the tfstate. We typically set tf tag to "-" for + // sensitive fields which were replaced with secretKeyRefs. + if f.TFTag != "-" { + r.addObservationField(f, field) + } if !IsObservation(f.Schema) { if f.AsBlocksMode { f.TFTag = strings.TrimSuffix(f.TFTag, ",omitempty") From e376ed83dd2a8ab00e3bc040a04c4851df8d1b41 Mon Sep 17 00:00:00 2001 From: Hasan Turken Date: Mon, 10 Apr 2023 14:11:32 +0300 Subject: [PATCH 3/3] Add comment for previously added observation types Signed-off-by: Hasan Turken --- pkg/types/builder.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/types/builder.go b/pkg/types/builder.go index a830a5bd..e7e59db1 100644 --- a/pkg/types/builder.go +++ b/pkg/types/builder.go @@ -280,6 +280,8 @@ func (r *resource) addObservationField(f *Field, field *types.Var) { for _, obsF := range r.obsFields { if obsF.Name() == field.Name() { // If the field is already added, we don't add it again. + // Some nested types could have been previously added as an + // observation type while building their schema: /~https://github.com/upbound/upjet/blob/b89baca4ae24c8fbd8eb403c353ca18916093e5e/pkg/types/builder.go#L206 return } }