Skip to content

Commit

Permalink
Move applying SSA merge default config to provider.
Browse files Browse the repository at this point in the history
Use correct Computed value for list merge keys
  • Loading branch information
JonathanO committed Mar 18, 2024
1 parent f785b4d commit 9380ba1
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 55 deletions.
53 changes: 53 additions & 0 deletions pkg/config/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ func NewProvider(schema []byte, prefix string, modulePath string, metadata []byt
p.Resources[name] = DefaultResource(name, terraformResource, terraformPluginFrameworkResource, providerMetadata.Resources[name], p.DefaultResourceOptions...)
p.Resources[name].useTerraformPluginSDKClient = isTerraformPluginSDK
p.Resources[name].useTerraformPluginFrameworkClient = isPluginFrameworkResource
p.injectServerSideApplyDefaults(p.Resources[name], terraformResource, "")
}
for i, refInjector := range p.refInjectors {
if err := refInjector.InjectReferences(p.Resources); err != nil {
Expand All @@ -360,6 +361,58 @@ func NewProvider(schema []byte, prefix string, modulePath string, metadata []byt
return p
}

func (p *Provider) injectServerSideApplyDefaults(cfg *Resource, res *schema.Resource, basePath string) { //nolint:gocyclo // Easier to follow the logic in a single function

for k, es := range res.Schema {

var fieldPath string
if basePath == "" {
fieldPath = k
} else {
fieldPath = fmt.Sprintf("%s.%s", basePath, k)
}

if r, ok := es.Elem.(*schema.Resource); ok {
if es.Type == schema.TypeList && es.MaxItems == 1 {
cfg.ServerSideApplyMergeStrategies[fieldPath] = MergeStrategy{
ListMergeStrategy: ListMergeStrategy{
MergeStrategy: ListTypeMap,
ListMapKeys: ListMapKeys{InjectedKey: InjectedKey{
Key: "ssamergekey",
DefaultValue: `"0"`,
}},
},
}
}
p.injectServerSideApplyDefaults(cfg, r, fieldPath)
} else {
switch es.Type { //nolint:exhaustive
case schema.TypeSet:
if el, ok := es.Elem.(*schema.Schema); ok {
switch el.Type { //nolint:exhaustive
case schema.TypeString, schema.TypeBool, schema.TypeInt, schema.TypeFloat:
cfg.ServerSideApplyMergeStrategies[fieldPath] = MergeStrategy{
ListMergeStrategy: ListMergeStrategy{
MergeStrategy: ListTypeSet,
},
}
}
}
case schema.TypeMap:
if el, ok := es.Elem.(*schema.Schema); ok {
switch el.Type { //nolint:exhaustive
case schema.TypeString, schema.TypeBool, schema.TypeInt, schema.TypeFloat:
// TODO(jono): I think this may be unnecessary since maps appear to default to granular?
cfg.ServerSideApplyMergeStrategies[fieldPath] = MergeStrategy{
MapMergeStrategy: MapTypeGranular,
}
}
}
}
}
}
}

// AddResourceConfigurator adds resource specific configurators.
func (p *Provider) AddResourceConfigurator(resource string, c ResourceConfiguratorFn) { //nolint:interfacer
// Note(turkenh): nolint reasoning - easier to provide a function without
Expand Down
56 changes: 1 addition & 55 deletions pkg/types/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ func NewBuilder(pkg *types.Package) *Builder {

// Build returns parameters and observation types built out of Terraform schema.
func (g *Builder) Build(cfg *config.Resource) (Generated, error) {
injectServerSideApplyDefaults(cfg, cfg.TerraformResource, "")
if err := injectServerSideApplyListMergeKeys(cfg); err != nil {
return Generated{}, errors.Wrapf(err, "cannot inject server-side apply merge keys for resource %q", cfg.Name)
}
Expand All @@ -86,60 +85,6 @@ func (g *Builder) Build(cfg *config.Resource) (Generated, error) {
}, errors.Wrapf(err, "cannot build the Types for resource %q", cfg.Name)
}

func injectServerSideApplyDefaults(cfg *config.Resource, res *schema.Resource, basePath string) { //nolint:gocyclo // Easier to follow the logic in a single function

for k, es := range res.Schema {
fieldPath := k
if basePath != "" {
fieldPath = fmt.Sprintf("%s.%s", basePath, k)
}

if el, ok := es.Elem.(*schema.Resource); ok {
if _, ok := cfg.ServerSideApplyMergeStrategies[fieldPath]; !ok {
if es.Type == schema.TypeList && es.MaxItems == 1 {
cfg.ServerSideApplyMergeStrategies[fieldPath] = config.MergeStrategy{
ListMergeStrategy: config.ListMergeStrategy{
MergeStrategy: config.ListTypeMap,
ListMapKeys: config.ListMapKeys{InjectedKey: config.InjectedKey{
Key: "ssamergekey",
DefaultValue: `"0"`,
}},
},
}
}
}
injectServerSideApplyDefaults(cfg, el, fieldPath)
} else {
if _, ok := cfg.ServerSideApplyMergeStrategies[fieldPath]; ok {
continue
}
switch es.Type { //nolint:exhaustive
case schema.TypeSet:
if el, ok := es.Elem.(*schema.Schema); ok {
switch el.Type { //nolint:exhaustive
case schema.TypeString, schema.TypeBool, schema.TypeInt, schema.TypeFloat:
cfg.ServerSideApplyMergeStrategies[fieldPath] = config.MergeStrategy{
ListMergeStrategy: config.ListMergeStrategy{
MergeStrategy: config.ListTypeSet,
},
}
}
}
case schema.TypeMap:
if el, ok := es.Elem.(*schema.Schema); ok {
switch el.Type { //nolint:exhaustive
case schema.TypeString, schema.TypeBool, schema.TypeInt, schema.TypeFloat:
// TODO(jono): I think this may be unnecessary since maps appear to default to granular?
cfg.ServerSideApplyMergeStrategies[fieldPath] = config.MergeStrategy{
MapMergeStrategy: config.MapTypeGranular,
}
}
}
}
}
}
}

func injectServerSideApplyListMergeKeys(cfg *config.Resource) error { //nolint:gocyclo // Easier to follow the logic in a single function
for f, s := range cfg.ServerSideApplyMergeStrategies {
if s.ListMergeStrategy.MergeStrategy != config.ListTypeMap {
Expand Down Expand Up @@ -170,6 +115,7 @@ func injectServerSideApplyListMergeKeys(cfg *config.Resource) error { //nolint:g
el.Schema[s.ListMergeStrategy.ListMapKeys.InjectedKey.Key] = &schema.Schema{
Type: schema.TypeString,
Required: true,
Computed: sch.Computed,
Description: descriptionInjectedKey,
}
if s.ListMergeStrategy.ListMapKeys.InjectedKey.DefaultValue != "" {
Expand Down

0 comments on commit 9380ba1

Please sign in to comment.