diff --git a/mmv1/products/appengine/StandardAppVersion.yaml b/mmv1/products/appengine/StandardAppVersion.yaml index 9d88080d88a4..f3a13a8eabb3 100644 --- a/mmv1/products/appengine/StandardAppVersion.yaml +++ b/mmv1/products/appengine/StandardAppVersion.yaml @@ -350,6 +350,8 @@ properties: default_from_api: true - !ruby/object:Api::Type::NestedObject name: 'automaticScaling' + # This flattener is entirely handwritten and must be updated with **any** new field or subfield + custom_flatten: 'templates/terraform/custom_flatten/appengine_standardappversion_automatic_scaling_handlenil.go.erb' description: | Automatic scaling is based on request rate, response latencies, and other application metrics. conflicts: diff --git a/mmv1/templates/terraform/custom_flatten/appengine_standardappversion_automatic_scaling_handlenil.go.erb b/mmv1/templates/terraform/custom_flatten/appengine_standardappversion_automatic_scaling_handlenil.go.erb new file mode 100644 index 000000000000..f79aa1ff1596 --- /dev/null +++ b/mmv1/templates/terraform/custom_flatten/appengine_standardappversion_automatic_scaling_handlenil.go.erb @@ -0,0 +1,185 @@ +<%# The license inside this block applies to this file. + # Copyright 2024 Google Inc. + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. +-%> +func flattenAppEngineStandardAppVersionAutomaticScaling(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["max_concurrent_requests"] = + flattenAppEngineStandardAppVersionAutomaticScalingMaxConcurrentRequests(original["maxConcurrentRequests"], d, config) + transformed["max_idle_instances"] = + flattenAppEngineStandardAppVersionAutomaticScalingMaxIdleInstances(original["maxIdleInstances"], d, config) + transformed["max_pending_latency"] = + flattenAppEngineStandardAppVersionAutomaticScalingMaxPendingLatency(original["maxPendingLatency"], d, config) + transformed["min_idle_instances"] = + flattenAppEngineStandardAppVersionAutomaticScalingMinIdleInstances(original["minIdleInstances"], d, config) + transformed["min_pending_latency"] = + flattenAppEngineStandardAppVersionAutomaticScalingMinPendingLatency(original["minPendingLatency"], d, config) + transformed["standard_scheduler_settings"] = + flattenAppEngineStandardAppVersionAutomaticScalingStandardSchedulerSettings(original["standardSchedulerSettings"], d, config) + + // begin handwritten code (all other parts of this file are forked from generated code) + // solve for the following diff when no scaling settings are configured: + // + // - automatic_scaling { + // - max_concurrent_requests = 0 -> null + // - max_idle_instances = 0 -> null + // - min_idle_instances = 0 -> null + // } + // + // this happens because the field is returned as: + // + //"automaticScaling": { + // "standardSchedulerSettings": {} + // }, + // + // this is hacky but avoids marking the field as computed, since it's in a oneof + // if any new fields are added to the block or explicit defaults start getting + // returned, it will need to be updated + if transformed["max_concurrent_requests"] == nil && // even primitives are nil at this stage if they're not returned by the API + transformed["max_idle_instances"] == nil && + transformed["max_pending_latency"] == nil && + transformed["min_idle_instances"] == nil && + transformed["min_pending_latency"] == nil && + transformed["standard_scheduler_settings"] == nil { + return nil + } + // end handwritten code + + return []interface{}{transformed} +} +func flattenAppEngineStandardAppVersionAutomaticScalingMaxConcurrentRequests(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 flattenAppEngineStandardAppVersionAutomaticScalingMaxIdleInstances(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 flattenAppEngineStandardAppVersionAutomaticScalingMaxPendingLatency(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenAppEngineStandardAppVersionAutomaticScalingMinIdleInstances(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 flattenAppEngineStandardAppVersionAutomaticScalingMinPendingLatency(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenAppEngineStandardAppVersionAutomaticScalingStandardSchedulerSettings(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["target_cpu_utilization"] = + flattenAppEngineStandardAppVersionAutomaticScalingStandardSchedulerSettingsTargetCpuUtilization(original["targetCpuUtilization"], d, config) + transformed["target_throughput_utilization"] = + flattenAppEngineStandardAppVersionAutomaticScalingStandardSchedulerSettingsTargetThroughputUtilization(original["targetThroughputUtilization"], d, config) + transformed["min_instances"] = + flattenAppEngineStandardAppVersionAutomaticScalingStandardSchedulerSettingsMinInstances(original["minInstances"], d, config) + transformed["max_instances"] = + flattenAppEngineStandardAppVersionAutomaticScalingStandardSchedulerSettingsMaxInstances(original["maxInstances"], d, config) + return []interface{}{transformed} +} +func flattenAppEngineStandardAppVersionAutomaticScalingStandardSchedulerSettingsTargetCpuUtilization(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenAppEngineStandardAppVersionAutomaticScalingStandardSchedulerSettingsTargetThroughputUtilization(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenAppEngineStandardAppVersionAutomaticScalingStandardSchedulerSettingsMinInstances(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 flattenAppEngineStandardAppVersionAutomaticScalingStandardSchedulerSettingsMaxInstances(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 +}