Skip to content

Commit 95e421b

Browse files
authored
Merge pull request #554 from sergenyalcin/backport-544-to-release-1.11
[Backport release-1.11] Backport 544 to release 1.11
2 parents a667e19 + 31bc693 commit 95e421b

17 files changed

Lines changed: 2148 additions & 182 deletions

File tree

pkg/config/conversion/conversions.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,9 @@ func (i *identityConversion) ConvertManaged(src, target resource.Managed) (bool,
261261
pv := fieldpath.Pave(srcRaw)
262262
for _, ex := range i.excludePaths {
263263
exPaths, err := pv.ExpandWildcards(ex)
264-
if err != nil {
264+
if fieldpath.IsNotFound(err) {
265+
continue
266+
} else if err != nil {
265267
return false, errors.Wrapf(err, "cannot expand wildcards in the fieldpath expression %s", ex)
266268
}
267269
for _, p := range exPaths {

pkg/config/resource.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import (
2727

2828
"github.com/crossplane/upjet/pkg/config/conversion"
2929
"github.com/crossplane/upjet/pkg/registry"
30+
"github.com/crossplane/upjet/pkg/types/markers/kubebuilder"
31+
"github.com/crossplane/upjet/pkg/types/structtag"
3032
)
3133

3234
// A ListType is a type of list.
@@ -685,6 +687,7 @@ func (m SchemaElementOptions) SetAddToObservation(el string) {
685687

686688
// AddToObservation returns true if the schema element at the specified path
687689
// should be added to the CRD type's Observation type.
690+
// Deprecated: Use SchemaElementOptions.AddToObservation instead.
688691
func (m SchemaElementOptions) AddToObservation(el string) bool {
689692
return m[el] != nil && m[el].AddToObservation
690693
}
@@ -799,6 +802,48 @@ func (m SchemaElementOptions) EmbeddedObject(el string) bool {
799802
return m[el] != nil && m[el].EmbeddedObject
800803
}
801804

805+
// SetInitProviderOverrides sets the InitProviderOverrides
806+
// for the specified key.
807+
// The key is a Terraform field path without the wildcard segments, like
808+
// a.b.c.
809+
func (m SchemaElementOptions) SetInitProviderOverrides(el string, o *InitProviderOverrides) {
810+
if m[el] == nil {
811+
m[el] = &SchemaElementOption{}
812+
}
813+
m[el].InitProviderOverrides = o
814+
}
815+
816+
// TagOverrides can be used to override the generated struct tags in
817+
// the generated InitProvider, ForProvider or Observation APIs for
818+
// the Terraform schema element.
819+
type TagOverrides struct {
820+
// TFTag can be set to override the generated tf struct tag
821+
// for the schema element. Tag's key cannot be overridden and if you specify
822+
// a key here, it will be ignored. Tag's name is only overridden
823+
// if you specify a non-empty name. Tag's omit policy and inline are always
824+
// overridden with what you specify here.
825+
TFTag *structtag.Value
826+
// JSONTag can be set to override the generated json struct tag
827+
// for the schema element. Tag's key cannot be overridden and if you specify
828+
// a key here, it will be ignored. Tag's name is only overridden
829+
// if you specify a non-empty name. Tag's omit policy and inline are always
830+
// overridden with what you specify here.
831+
JSONTag *structtag.Value
832+
}
833+
834+
// InitProviderOverrides is a set of overrides for the generated InitProvider
835+
// field corresponding to a Terraform schema element.
836+
type InitProviderOverrides struct {
837+
// TagOverrides sets tag overrides for the generated struct tags
838+
// in the InitProvider API.
839+
TagOverrides
840+
// Options sets the override for the kubebuilder marker options
841+
// to be used for the generated InitProvider field corresponding to a
842+
// Terraform schema element. A kubebuilder marker option is only overridden
843+
// if it's not nil.
844+
KubebuilderOptions *kubebuilder.Options
845+
}
846+
802847
// SchemaElementOption represents configuration options on a schema element.
803848
type SchemaElementOption struct {
804849
// AddToObservation is set to true if the field represented by
@@ -809,4 +854,7 @@ type SchemaElementOption struct {
809854
// a schema element is to be embedded into its parent instead of being
810855
// generated as a single element list.
811856
EmbeddedObject bool
857+
// InitProviderOverrides is set to override the generated InitProvider field
858+
// corresponding to a schema element.
859+
InitProviderOverrides *InitProviderOverrides
812860
}

pkg/controller/ignored_tfpluginsdk.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ func getTerraformIgnoreChanges(forProvider, initProvider map[string]any) []strin
2222
func getIgnoredFieldsMap(format string, forProvider, initProvider map[string]any) []string {
2323
ignored := []string{}
2424

25-
for k := range initProvider {
25+
for k, v := range initProvider {
26+
if v == nil {
27+
continue
28+
}
29+
2630
if _, ok := forProvider[k]; !ok {
2731
ignored = append(ignored, fmt.Sprintf(format, k))
2832
} else {

pkg/types/builder.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"go/token"
1010
"go/types"
1111
"sort"
12-
"strings"
1312

1413
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1514
twtypes "github.com/muvaf/typewriter/pkg/types"
@@ -168,7 +167,7 @@ func (g *Builder) buildResource(res *schema.Resource, cfg *config.Resource, tfPa
168167
return nil, nil, nil, err
169168
}
170169
}
171-
f.AddToResource(g, r, typeNames, cfg.SchemaElementOptions.AddToObservation(cPath))
170+
f.AddToResource(g, r, typeNames, ptr.Deref(cfg.SchemaElementOptions[cPath], config.SchemaElementOption{}))
172171
}
173172

174173
paramType, obsType, initType := g.AddToBuilder(typeNames, r)
@@ -282,8 +281,10 @@ func (g *Builder) buildSchema(f *Field, cfg *config.Resource, names []string, cp
282281
tParam = types.NewSlice(paramType)
283282
tInit = types.NewSlice(initType)
284283
}
284+
opt := ptr.Deref(cfg.SchemaElementOptions[cpath], config.SchemaElementOption{})
285+
initProviderOverrides := ptr.Deref(opt.InitProviderOverrides, config.InitProviderOverrides{})
285286
r.addParameterField(f, types.NewField(token.NoPos, g.Package, f.Name.Camel, tParam, false))
286-
r.addInitField(f, types.NewField(token.NoPos, g.Package, f.Name.Camel, tInit, false), g, nil)
287+
r.addInitField(f, types.NewField(token.NoPos, g.Package, f.Name.Camel, tInit, false), g, nil, initProviderOverrides.TagOverrides)
287288
}
288289
default:
289290
if paramType == nil {
@@ -400,32 +401,30 @@ func (r *resource) addParameterField(f *Field, field *types.Var) {
400401
requiredBySchema = false
401402
// If the field is not a terraform field, we should not require it in init,
402403
// as it is not an initProvider field.
403-
r.topLevelRequiredParams = append(r.topLevelRequiredParams, newTopLevelRequiredParam(f.TransformedName, f.TFTag != "-"))
404+
r.topLevelRequiredParams = append(r.topLevelRequiredParams, newTopLevelRequiredParam(f.TransformedName, !f.TFTag.AlwaysOmitted()))
404405
}
405406

406407
// Note(lsviben): Only fields which are not also initProvider fields should have a required kubebuilder comment.
407-
f.Comment.Required = ptr.To(requiredBySchema && !f.isInit())
408+
f.Comment.KubebuilderOptions.Required = ptr.To(requiredBySchema && !f.isInit())
408409

409410
// For removing omitempty tag from json tag, we are just checking if the field is required by the schema.
410411
if requiredBySchema {
411412
// Required fields should not have omitempty tag in json tag.
412-
// TODO(muvaf): This overrides user intent if they provided custom
413-
// JSON tag.
414-
r.paramTags = append(r.paramTags, fmt.Sprintf(`json:"%s" tf:"%s"`, strings.TrimSuffix(f.JSONTag, ",omitempty"), f.TFTag))
413+
r.paramTags = append(r.paramTags, fmt.Sprintf("%s %s", f.JSONTag.NoOmit(), f.TFTag))
415414
} else {
416-
r.paramTags = append(r.paramTags, fmt.Sprintf(`json:"%s" tf:"%s"`, f.JSONTag, f.TFTag))
415+
r.paramTags = append(r.paramTags, fmt.Sprintf("%s %s", f.JSONTag, f.TFTag))
417416
}
418417

419418
r.paramFields = append(r.paramFields, field)
420419
}
421420

422-
func (r *resource) addInitField(f *Field, field *types.Var, g *Builder, typeNames *types.TypeName) {
421+
func (r *resource) addInitField(f *Field, field *types.Var, g *Builder, typeNames *types.TypeName, o config.TagOverrides) {
423422
// If the field is not an init field, we don't add it.
424423
if !f.isInit() {
425424
return
426425
}
427426

428-
r.initTags = append(r.initTags, fmt.Sprintf(`json:"%s" tf:"%s"`, f.JSONTag, f.TFTag))
427+
r.initTags = append(r.initTags, fmt.Sprintf("%s %s", f.JSONTag.OverrideFrom(o.JSONTag), f.TFTag.OverrideFrom(o.TFTag)))
429428

430429
// If the field is a nested type, we need to add it as the init type.
431430
if f.InitType != nil {
@@ -449,7 +448,7 @@ func (r *resource) addObservationField(f *Field, field *types.Var) {
449448
}
450449
}
451450
r.obsFields = append(r.obsFields, field)
452-
r.obsTags = append(r.obsTags, fmt.Sprintf(`json:"%s" tf:"%s"`, f.JSONTag, f.TFTag))
451+
r.obsTags = append(r.obsTags, fmt.Sprintf("%s %s", f.JSONTag, f.TFTag))
453452
}
454453

455454
func (r *resource) addReferenceFields(g *Builder, paramName *types.TypeName, field *Field, isInit bool) {

pkg/types/comments/comment.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/crossplane/upjet/pkg/config"
1111
"github.com/crossplane/upjet/pkg/types/markers"
12+
"github.com/crossplane/upjet/pkg/types/structtag"
1213
)
1314

1415
// Option is a comment option
@@ -21,10 +22,10 @@ func WithReferenceConfig(cfg config.Reference) Option {
2122
}
2223
}
2324

24-
// WithTFTag returns a comment options with input tf tag
25-
func WithTFTag(s string) Option {
25+
// WithTFTag returns a comment options with input tf tag.
26+
func WithTFTag(t string) Option {
2627
return func(c *Comment) {
27-
c.FieldTFTag = &s
28+
c.FieldTFTag = structtag.MustParseTF(t)
2829
}
2930
}
3031

pkg/types/comments/comment_test.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@ import (
88
"reflect"
99
"testing"
1010

11+
"github.com/crossplane/crossplane-runtime/pkg/errors"
1112
"github.com/crossplane/crossplane-runtime/pkg/test"
1213
"github.com/google/go-cmp/cmp"
13-
"github.com/pkg/errors"
1414

1515
"github.com/crossplane/upjet/pkg/config"
1616
"github.com/crossplane/upjet/pkg/types/markers"
17+
"github.com/crossplane/upjet/pkg/types/structtag"
1718
)
1819

19-
func TestComment_Build(t *testing.T) {
20-
tftag := "-"
20+
func TestCommentBuild(t *testing.T) {
21+
tftag := structtag.NewTF(structtag.WithOmit(structtag.OmitAlways))
2122
type args struct {
2223
text string
2324
opts []Option
@@ -67,7 +68,7 @@ yes, this is a test`,
6768
`,
6869
mopts: markers.Options{
6970
UpjetOptions: markers.UpjetOptions{
70-
FieldTFTag: &tftag,
71+
FieldTFTag: tftag,
7172
},
7273
},
7374
},
@@ -98,7 +99,7 @@ yes, this is a test`,
9899
`,
99100
mopts: markers.Options{
100101
UpjetOptions: markers.UpjetOptions{
101-
FieldTFTag: &tftag,
102+
FieldTFTag: tftag,
102103
},
103104
},
104105
},
@@ -120,7 +121,7 @@ yes, this is a test`,
120121
`,
121122
mopts: markers.Options{
122123
UpjetOptions: markers.UpjetOptions{
123-
FieldTFTag: &tftag,
124+
FieldTFTag: tftag,
124125
},
125126
CrossplaneOptions: markers.CrossplaneOptions{
126127
Reference: config.Reference{
@@ -138,7 +139,7 @@ yes, this is a test`,
138139
`,
139140
},
140141
want: want{
141-
err: errors.New("cannot parse as a upjet prefix: +upjet:unsupported:key=value"),
142+
err: errors.New("cannot parse as an upjet prefix: +upjet:unsupported:key=value"),
142143
},
143144
},
144145
}
@@ -151,7 +152,9 @@ yes, this is a test`,
151152
if gotErr != nil {
152153
return
153154
}
154-
if diff := cmp.Diff(tc.want.mopts, c.Options); diff != "" {
155+
if diff := cmp.Diff(tc.want.mopts, c.Options, cmp.Comparer(func(v1, v2 structtag.Value) bool {
156+
return v1.String() == v2.String()
157+
})); diff != "" {
155158
t.Errorf("comment.New(...) opts = %v, want %v", c.Options, tc.want.mopts)
156159
}
157160
got := c.Build()

0 commit comments

Comments
 (0)