diff --git a/pkg/config/config.go b/pkg/config/config.go index 447d8fca..6aa93ba4 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -25,6 +25,8 @@ type Config struct { // Resources contains generator instructions for individual CRDs within an // API Resources map[string]ResourceConfig `json:"resources"` + // MarkerShapes contains fields associated with empty structs used as markers + MarkerShapes []string `json:"marker_shapes,omitempty"` // CRDs to ignore. ACK generator would skip these resources. Ignore IgnoreSpec `json:"ignore"` // Contains generator instructions for individual API operations. @@ -151,6 +153,17 @@ func (c *Config) GetCustomMapFieldMembers() []string { return members } +// IsMarkerShape returns true if a given shape name is a marker shape, +// otherwise returns false +func (c *Config) IsMarkerShape(shapeName string) bool { + for _, markerShape := range c.MarkerShapes { + if markerShape == shapeName { + return true + } + } + return false +} + // New returns a new Config object given a supplied // path to a config file func New( diff --git a/pkg/generate/code/set_sdk.go b/pkg/generate/code/set_sdk.go index 75c914a1..58f7ea35 100644 --- a/pkg/generate/code/set_sdk.go +++ b/pkg/generate/code/set_sdk.go @@ -1388,8 +1388,13 @@ func varEmptyConstructorK8sType( switch shape.Type { case "structure": - // f0 := &svcapitypes.BookData{} - out += fmt.Sprintf("%s%s := &%s{}\n", indent, varName, goType) + if r.Config().IsMarkerShape(shape.ShapeName) { + // f0 := []byte{} + out += fmt.Sprintf("%s%s := []byte{}\n", indent, varName) + } else { + // f0 := &svcapitypes.BookData{} + out += fmt.Sprintf("%s%s := &%s{}\n", indent, varName, goType) + } case "list", "map": // f0 := []*string{} out += fmt.Sprintf("%s%s := %s{}\n", indent, varName, goType) diff --git a/pkg/model/model.go b/pkg/model/model.go index 10071835..1cb2cdb9 100644 --- a/pkg/model/model.go +++ b/pkg/model/model.go @@ -16,6 +16,7 @@ package model import ( "errors" "fmt" + "slices" "sort" "strings" @@ -395,6 +396,11 @@ func (m *Model) IsShapeUsedInCRDs(shapeName string) bool { return false } +// IsMarkerShape return true if the supplied shape name is a marker shape +func (m *Model) IsMarkerShape(shapeName string) bool { + return slices.Contains(m.cfg.MarkerShapes, shapeName) +} + // GetTypeDefs returns a slice of `TypeDef` pointers func (m *Model) GetTypeDefs() ([]*TypeDef, error) { if m.typeDefs != nil { @@ -471,6 +477,12 @@ func (m *Model) getShapeCleanGoType(shape *awssdkmodel.Shape) string { // otherwise there is no DeepCopy support return "*metav1.Time" case "structure": + if len(shape.MemberRefs) == 0 { + if m.cfg.IsMarkerShape(shape.ShapeName) { + return "[]byte" + } + panic(fmt.Sprintf("structure %s has no fields, either configure it as a `marker_shape` or manually set the field type", shape.ShapeName)) + } // There are shapes that are called things like DBProxyStatus that are // fields in a DBProxy CRD... we need to ensure the type names don't // conflict. Also, the name of the Go type in the generated code is