Skip to content

feat(spanner): add instance asymmetric autoscaling options support in spanner instance resource #8503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
3 changes: 3 additions & 0 deletions .changelog/12100.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
spanner: added `asymmetric_autoscaling_options` field to `google_spanner_instance`
```
269 changes: 269 additions & 0 deletions google-beta/services/spanner/resource_spanner_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,60 @@ the instance.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"asymmetric_autoscaling_options": {
Type: schema.TypeList,
Optional: true,
Description: `Asymmetric autoscaling options for specific replicas.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"overrides": {
Type: schema.TypeList,
Required: true,
Description: `A nested object resource`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"autoscaling_limits": {
Type: schema.TypeList,
Required: true,
Description: `A nested object resource`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"max_nodes": {
Type: schema.TypeInt,
Required: true,
Description: `The maximum number of nodes for this specific replica.`,
},
"min_nodes": {
Type: schema.TypeInt,
Required: true,
Description: `The minimum number of nodes for this specific replica.`,
},
},
},
},
},
},
},
"replica_selection": {
Type: schema.TypeList,
Required: true,
Description: `A nested object resource`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"location": {
Type: schema.TypeString,
Required: true,
Description: `The location of the replica to apply asymmetric autoscaling options.`,
},
},
},
},
},
},
},
"autoscaling_limits": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -829,6 +883,8 @@ func flattenSpannerInstanceAutoscalingConfig(v interface{}, d *schema.ResourceDa
flattenSpannerInstanceAutoscalingConfigAutoscalingLimits(original["autoscalingLimits"], d, config)
transformed["autoscaling_targets"] =
flattenSpannerInstanceAutoscalingConfigAutoscalingTargets(original["autoscalingTargets"], d, config)
transformed["asymmetric_autoscaling_options"] =
flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptions(original["asymmetricAutoscalingOptions"], d, config)
return []interface{}{transformed}
}
func flattenSpannerInstanceAutoscalingConfigAutoscalingLimits(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
Expand Down Expand Up @@ -967,6 +1023,104 @@ func flattenSpannerInstanceAutoscalingConfigAutoscalingTargetsStorageUtilization
return v // let terraform core handle it otherwise
}

func flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return v
}
l := v.([]interface{})
transformed := make([]interface{}, 0, len(l))
for _, raw := range l {
original := raw.(map[string]interface{})
if len(original) < 1 {
// Do not include empty json objects coming back from the api
continue
}
transformed = append(transformed, map[string]interface{}{
"replica_selection": flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsReplicaSelection(original["replicaSelection"], d, config),
"overrides": flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverrides(original["overrides"], d, config),
})
}
return transformed
}
func flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsReplicaSelection(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["location"] =
flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsReplicaSelectionLocation(original["location"], d, config)
return []interface{}{transformed}
}
func flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsReplicaSelectionLocation(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}

func flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverrides(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["autoscaling_limits"] =
flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimits(original["autoscalingLimits"], d, config)
return []interface{}{transformed}
}
func flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimits(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
}
original := v.(map[string]interface{})
if len(original) == 0 {
return nil
}
transformed := make(map[string]interface{})
transformed["min_nodes"] =
flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimitsMinNodes(original["minNodes"], d, config)
transformed["max_nodes"] =
flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimitsMaxNodes(original["maxNodes"], d, config)
return []interface{}{transformed}
}
func flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimitsMinNodes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
// Handles the string fixed64 format
if strVal, ok := v.(string); ok {
if intVal, err := tpgresource.StringToFixed64(strVal); err == nil {
return intVal
}
}

// number values are represented as float64
if floatVal, ok := v.(float64); ok {
intVal := int(floatVal)
return intVal
}

return v // let terraform core handle it otherwise
}

func flattenSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimitsMaxNodes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
// Handles the string fixed64 format
if strVal, ok := v.(string); ok {
if intVal, err := tpgresource.StringToFixed64(strVal); err == nil {
return intVal
}
}

// number values are represented as float64
if floatVal, ok := v.(float64); ok {
intVal := int(floatVal)
return intVal
}

return v // let terraform core handle it otherwise
}

func flattenSpannerInstanceEdition(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
return v
}
Expand Down Expand Up @@ -1043,6 +1197,13 @@ func expandSpannerInstanceAutoscalingConfig(v interface{}, d tpgresource.Terrafo
transformed["autoscalingTargets"] = transformedAutoscalingTargets
}

transformedAsymmetricAutoscalingOptions, err := expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptions(original["asymmetric_autoscaling_options"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAsymmetricAutoscalingOptions); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["asymmetricAutoscalingOptions"] = transformedAsymmetricAutoscalingOptions
}

return transformed, nil
}

Expand Down Expand Up @@ -1136,6 +1297,111 @@ func expandSpannerInstanceAutoscalingConfigAutoscalingTargetsStorageUtilizationP
return v, nil
}

func expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptions(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
for _, raw := range l {
if raw == nil {
continue
}
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedReplicaSelection, err := expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsReplicaSelection(original["replica_selection"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedReplicaSelection); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["replicaSelection"] = transformedReplicaSelection
}

transformedOverrides, err := expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverrides(original["overrides"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedOverrides); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["overrides"] = transformedOverrides
}

req = append(req, transformed)
}
return req, nil
}

func expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsReplicaSelection(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedLocation, err := expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsReplicaSelectionLocation(original["location"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedLocation); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["location"] = transformedLocation
}

return transformed, nil
}

func expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsReplicaSelectionLocation(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverrides(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedAutoscalingLimits, err := expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimits(original["autoscaling_limits"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedAutoscalingLimits); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["autoscalingLimits"] = transformedAutoscalingLimits
}

return transformed, nil
}

func expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimits(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})

transformedMinNodes, err := expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimitsMinNodes(original["min_nodes"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedMinNodes); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["minNodes"] = transformedMinNodes
}

transformedMaxNodes, err := expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimitsMaxNodes(original["max_nodes"], d, config)
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedMaxNodes); val.IsValid() && !tpgresource.IsEmptyValue(val) {
transformed["maxNodes"] = transformedMaxNodes
}

return transformed, nil
}

func expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimitsMinNodes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandSpannerInstanceAutoscalingConfigAsymmetricAutoscalingOptionsOverridesAutoscalingLimitsMaxNodes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}

func expandSpannerInstanceEdition(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
return v, nil
}
Expand Down Expand Up @@ -1219,6 +1485,9 @@ func resourceSpannerInstanceUpdateEncoder(d *schema.ResourceData, meta interface
if d.HasChange("autoscaling_config.0.autoscaling_targets.0.storage_utilization_percent") {
updateMask = append(updateMask, "autoscalingConfig.autoscalingTargets.storageUtilizationPercent")
}
if d.HasChange("autoscaling_config.0.asymmetric_autoscaling_options") {
updateMask = append(updateMask, "autoscalingConfig.asymmetricAutoscalingOptions")
}
}
}
newObj["fieldMask"] = strings.Join(updateMask, ",")
Expand Down
Loading