From be7372e5e9785a27c6cbba9d1d665b3153f675c6 Mon Sep 17 00:00:00 2001 From: The Magician Date: Thu, 12 Oct 2023 16:23:17 -0400 Subject: [PATCH] promote gkeonprem resources to GA (#9214) (#16237) * promote gkeonprem resources to GA * fix update test [upstream:4dc1173c6943b348308001f9071b37581aa75e01] Signed-off-by: Modular Magician --- .changelog/9214.txt | 6 + google/fwmodels/provider_model.go | 1 + google/fwprovider/framework_provider.go | 6 + google/fwtransport/framework_config.go | 10 + google/provider/provider.go | 16 +- .../services/gkeonprem/gkeonprem_operation.go | 144 + ...urce_gkeonprem_bare_metal_admin_cluster.go | 2659 ++++++++++ ...bare_metal_admin_cluster_generated_test.go | 233 + .../resource_gkeonprem_bare_metal_cluster.go | 4593 +++++++++++++++++ ...nprem_bare_metal_cluster_generated_test.go | 424 ++ ...ce_gkeonprem_bare_metal_cluster_sweeper.go | 139 + ...ource_gkeonprem_bare_metal_cluster_test.go | 574 ++ ...resource_gkeonprem_bare_metal_node_pool.go | 991 ++++ ...rem_bare_metal_node_pool_generated_test.go | 301 ++ ...rce_gkeonprem_bare_metal_node_pool_test.go | 225 + .../resource_gkeonprem_vmware_cluster.go | 3459 +++++++++++++ ...gkeonprem_vmware_cluster_generated_test.go | 355 ++ ...source_gkeonprem_vmware_cluster_sweeper.go | 139 + .../resource_gkeonprem_vmware_cluster_test.go | 481 ++ .../resource_gkeonprem_vmware_node_pool.go | 1352 +++++ ...eonprem_vmware_node_pool_generated_test.go | 245 + ...urce_gkeonprem_vmware_node_pool_sweeper.go | 139 + ...esource_gkeonprem_vmware_node_pool_test.go | 187 + google/sweeper/gcp_sweeper_test.go | 1 + google/transport/config.go | 9 + ...rem_bare_metal_admin_cluster.html.markdown | 4 - ...gkeonprem_bare_metal_cluster.html.markdown | 5 - ...eonprem_bare_metal_node_pool.html.markdown | 6 - .../r/gkeonprem_vmware_cluster.html.markdown | 5 - .../gkeonprem_vmware_node_pool.html.markdown | 6 - 30 files changed, 16687 insertions(+), 28 deletions(-) create mode 100644 .changelog/9214.txt create mode 100644 google/services/gkeonprem/resource_gkeonprem_bare_metal_admin_cluster.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_bare_metal_admin_cluster_generated_test.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_generated_test.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_sweeper.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_generated_test.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_vmware_cluster.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_vmware_cluster_generated_test.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_vmware_cluster_sweeper.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_vmware_node_pool.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_generated_test.go create mode 100644 google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_sweeper.go diff --git a/.changelog/9214.txt b/.changelog/9214.txt new file mode 100644 index 00000000000..3cd97daba7c --- /dev/null +++ b/.changelog/9214.txt @@ -0,0 +1,6 @@ +```release-note:enhancement +gkeonprem: promoted `google_gkeonprem_bare_metal_admin_cluster`, `google_gkeonprem_bare_metal_cluster`, and `google_gkeonprem_bare_metal_node_pool` resources to GA +``` +```release-note:enhancement +gkeonprem: promoted `google_gkeonprem_vmware_cluster` and `google_gkeonprem_vmware_node_pool` resources to GA +``` diff --git a/google/fwmodels/provider_model.go b/google/fwmodels/provider_model.go index 32a1e24bb6b..cd262cb376d 100644 --- a/google/fwmodels/provider_model.go +++ b/google/fwmodels/provider_model.go @@ -83,6 +83,7 @@ type ProviderModel struct { GKEBackupCustomEndpoint types.String `tfsdk:"gke_backup_custom_endpoint"` GKEHubCustomEndpoint types.String `tfsdk:"gke_hub_custom_endpoint"` GKEHub2CustomEndpoint types.String `tfsdk:"gke_hub2_custom_endpoint"` + GkeonpremCustomEndpoint types.String `tfsdk:"gkeonprem_custom_endpoint"` HealthcareCustomEndpoint types.String `tfsdk:"healthcare_custom_endpoint"` IAM2CustomEndpoint types.String `tfsdk:"iam2_custom_endpoint"` IAMBetaCustomEndpoint types.String `tfsdk:"iam_beta_custom_endpoint"` diff --git a/google/fwprovider/framework_provider.go b/google/fwprovider/framework_provider.go index 0e76d7cabc2..4276ec064f0 100644 --- a/google/fwprovider/framework_provider.go +++ b/google/fwprovider/framework_provider.go @@ -482,6 +482,12 @@ func (p *FrameworkProvider) Schema(_ context.Context, _ provider.SchemaRequest, transport_tpg.CustomEndpointValidator(), }, }, + "gkeonprem_custom_endpoint": &schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + transport_tpg.CustomEndpointValidator(), + }, + }, "healthcare_custom_endpoint": &schema.StringAttribute{ Optional: true, Validators: []validator.String{ diff --git a/google/fwtransport/framework_config.go b/google/fwtransport/framework_config.go index c4473788686..cf513bdd45c 100644 --- a/google/fwtransport/framework_config.go +++ b/google/fwtransport/framework_config.go @@ -108,6 +108,7 @@ type FrameworkProviderConfig struct { GKEBackupBasePath string GKEHubBasePath string GKEHub2BasePath string + GkeonpremBasePath string HealthcareBasePath string IAM2BasePath string IAMBetaBasePath string @@ -246,6 +247,7 @@ func (p *FrameworkProviderConfig) LoadAndValidateFramework(ctx context.Context, p.GKEBackupBasePath = data.GKEBackupCustomEndpoint.ValueString() p.GKEHubBasePath = data.GKEHubCustomEndpoint.ValueString() p.GKEHub2BasePath = data.GKEHub2CustomEndpoint.ValueString() + p.GkeonpremBasePath = data.GkeonpremCustomEndpoint.ValueString() p.HealthcareBasePath = data.HealthcareCustomEndpoint.ValueString() p.IAM2BasePath = data.IAM2CustomEndpoint.ValueString() p.IAMBetaBasePath = data.IAMBetaCustomEndpoint.ValueString() @@ -876,6 +878,14 @@ func (p *FrameworkProviderConfig) HandleDefaults(ctx context.Context, data *fwmo data.GKEHub2CustomEndpoint = types.StringValue(customEndpoint.(string)) } } + if data.GkeonpremCustomEndpoint.IsNull() { + customEndpoint := transport_tpg.MultiEnvDefault([]string{ + "GOOGLE_GKEONPREM_CUSTOM_ENDPOINT", + }, transport_tpg.DefaultBasePaths[transport_tpg.GkeonpremBasePathKey]) + if customEndpoint != nil { + data.GkeonpremCustomEndpoint = types.StringValue(customEndpoint.(string)) + } + } if data.HealthcareCustomEndpoint.IsNull() { customEndpoint := transport_tpg.MultiEnvDefault([]string{ "GOOGLE_HEALTHCARE_CUSTOM_ENDPOINT", diff --git a/google/provider/provider.go b/google/provider/provider.go index d1191c145f2..fa2ba92fcbb 100644 --- a/google/provider/provider.go +++ b/google/provider/provider.go @@ -70,6 +70,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/services/gkebackup" "github.com/hashicorp/terraform-provider-google/google/services/gkehub" "github.com/hashicorp/terraform-provider-google/google/services/gkehub2" + "github.com/hashicorp/terraform-provider-google/google/services/gkeonprem" "github.com/hashicorp/terraform-provider-google/google/services/healthcare" "github.com/hashicorp/terraform-provider-google/google/services/iam2" "github.com/hashicorp/terraform-provider-google/google/services/iambeta" @@ -525,6 +526,11 @@ func Provider() *schema.Provider { Optional: true, ValidateFunc: transport_tpg.ValidateCustomEndpoint, }, + "gkeonprem_custom_endpoint": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: transport_tpg.ValidateCustomEndpoint, + }, "healthcare_custom_endpoint": { Type: schema.TypeString, Optional: true, @@ -1003,9 +1009,9 @@ func DatasourceMapWithErrors() (map[string]*schema.Resource, error) { }) } -// Generated resources: 332 +// Generated resources: 337 // Generated IAM resources: 207 -// Total generated resources: 539 +// Total generated resources: 544 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -1364,6 +1370,11 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_gke_hub_scope_iam_member": tpgiamresource.ResourceIamMember(gkehub2.GKEHub2ScopeIamSchema, gkehub2.GKEHub2ScopeIamUpdaterProducer, gkehub2.GKEHub2ScopeIdParseFunc), "google_gke_hub_scope_iam_policy": tpgiamresource.ResourceIamPolicy(gkehub2.GKEHub2ScopeIamSchema, gkehub2.GKEHub2ScopeIamUpdaterProducer, gkehub2.GKEHub2ScopeIdParseFunc), "google_gke_hub_scope_rbac_role_binding": gkehub2.ResourceGKEHub2ScopeRBACRoleBinding(), + "google_gkeonprem_bare_metal_admin_cluster": gkeonprem.ResourceGkeonpremBareMetalAdminCluster(), + "google_gkeonprem_bare_metal_cluster": gkeonprem.ResourceGkeonpremBareMetalCluster(), + "google_gkeonprem_bare_metal_node_pool": gkeonprem.ResourceGkeonpremBareMetalNodePool(), + "google_gkeonprem_vmware_cluster": gkeonprem.ResourceGkeonpremVmwareCluster(), + "google_gkeonprem_vmware_node_pool": gkeonprem.ResourceGkeonpremVmwareNodePool(), "google_healthcare_consent_store": healthcare.ResourceHealthcareConsentStore(), "google_healthcare_consent_store_iam_binding": tpgiamresource.ResourceIamBinding(healthcare.HealthcareConsentStoreIamSchema, healthcare.HealthcareConsentStoreIamUpdaterProducer, healthcare.HealthcareConsentStoreIdParseFunc), "google_healthcare_consent_store_iam_member": tpgiamresource.ResourceIamMember(healthcare.HealthcareConsentStoreIamSchema, healthcare.HealthcareConsentStoreIamUpdaterProducer, healthcare.HealthcareConsentStoreIdParseFunc), @@ -1841,6 +1852,7 @@ func ProviderConfigure(ctx context.Context, d *schema.ResourceData, p *schema.Pr config.GKEBackupBasePath = d.Get("gke_backup_custom_endpoint").(string) config.GKEHubBasePath = d.Get("gke_hub_custom_endpoint").(string) config.GKEHub2BasePath = d.Get("gke_hub2_custom_endpoint").(string) + config.GkeonpremBasePath = d.Get("gkeonprem_custom_endpoint").(string) config.HealthcareBasePath = d.Get("healthcare_custom_endpoint").(string) config.IAM2BasePath = d.Get("iam2_custom_endpoint").(string) config.IAMBetaBasePath = d.Get("iam_beta_custom_endpoint").(string) diff --git a/google/services/gkeonprem/gkeonprem_operation.go b/google/services/gkeonprem/gkeonprem_operation.go index ef611fd9d21..3c5ad5930b7 100644 --- a/google/services/gkeonprem/gkeonprem_operation.go +++ b/google/services/gkeonprem/gkeonprem_operation.go @@ -1,3 +1,147 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package gkeonprem + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + + cloudresourcemanager "google.golang.org/api/cloudresourcemanager/v1" +) + +type gkeonpremOpError struct { + *cloudresourcemanager.Status +} + +func (e gkeonpremOpError) Error() string { + var validationCheck map[string]interface{} + + for _, msg := range e.Details { + detail := make(map[string]interface{}) + if err := json.Unmarshal(msg, &detail); err != nil { + continue + } + + if _, ok := detail["validationCheck"]; ok { + delete(detail, "@type") + validationCheck = detail + } + } + + if validationCheck != nil { + bytes, err := json.MarshalIndent(validationCheck, "", " ") + if err != nil { + return fmt.Sprintf("Error code %v message: %s validation check: %s", e.Code, e.Message, validationCheck) + } + + return fmt.Sprintf("Error code %v message: %s\n %s", e.Code, e.Message, bytes) + } + + return fmt.Sprintf("Error code %v, message: %s", e.Code, e.Message) +} + +type gkeonpremOperationWaiter struct { + Config *transport_tpg.Config + UserAgent string + Project string + Op tpgresource.CommonOperation +} + +func (w *gkeonpremOperationWaiter) State() string { + if w == nil { + return fmt.Sprintf("Operation is nil!") + } + + return fmt.Sprintf("done: %v", w.Op.Done) +} + +func (w *gkeonpremOperationWaiter) Error() error { + if w != nil && w.Op.Error != nil { + return &gkeonpremOpError{w.Op.Error} + } + return nil +} + +func (w *gkeonpremOperationWaiter) IsRetryable(error) bool { + return false +} + +func (w *gkeonpremOperationWaiter) SetOp(op interface{}) error { + if err := tpgresource.Convert(op, &w.Op); err != nil { + return err + } + return nil +} + +func (w *gkeonpremOperationWaiter) OpName() string { + if w == nil { + return "" + } + + return w.Op.Name +} + +func (w *gkeonpremOperationWaiter) PendingStates() []string { + return []string{"done: false"} +} + +func (w *gkeonpremOperationWaiter) TargetStates() []string { + return []string{"done: true"} +} + +func (w *gkeonpremOperationWaiter) QueryOp() (interface{}, error) { + if w == nil { + return nil, fmt.Errorf("Cannot query operation, it's unset or nil.") + } + // Returns the proper get. + url := fmt.Sprintf("%s%s", w.Config.GkeonpremBasePath, w.Op.Name) + + return transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: w.Config, + Method: "GET", + Project: w.Project, + RawURL: url, + UserAgent: w.UserAgent, + }) +} + +func creategkeonpremWaiter(config *transport_tpg.Config, op map[string]interface{}, project, activity, userAgent string) (*gkeonpremOperationWaiter, error) { + w := &gkeonpremOperationWaiter{ + Config: config, + UserAgent: userAgent, + Project: project, + } + if err := w.SetOp(op); err != nil { + return nil, err + } + return w, nil +} + +// nolint: deadcode,unused +func GkeonpremOperationWaitTimeWithResponse(config *transport_tpg.Config, op map[string]interface{}, response *map[string]interface{}, project, activity, userAgent string, timeout time.Duration) error { + w, err := creategkeonpremWaiter(config, op, project, activity, userAgent) + if err != nil { + return err + } + if err := tpgresource.OperationWait(w, activity, timeout, config.PollInterval); err != nil { + return err + } + return json.Unmarshal([]byte(w.Op.Response), response) +} + +func GkeonpremOperationWaitTime(config *transport_tpg.Config, op map[string]interface{}, project, activity, userAgent string, timeout time.Duration) error { + if val, ok := op["name"]; !ok || val == "" { + // This was a synchronous call - there is no operation to wait for. + return nil + } + w, err := creategkeonpremWaiter(config, op, project, activity, userAgent) + if err != nil { + // If w is nil, the op was synchronous. + return err + } + return tpgresource.OperationWait(w, activity, timeout, config.PollInterval) +} diff --git a/google/services/gkeonprem/resource_gkeonprem_bare_metal_admin_cluster.go b/google/services/gkeonprem/resource_gkeonprem_bare_metal_admin_cluster.go new file mode 100644 index 00000000000..ad3ca66f21b --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_bare_metal_admin_cluster.go @@ -0,0 +1,2659 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-provider-google/google/verify" +) + +func ResourceGkeonpremBareMetalAdminCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceGkeonpremBareMetalAdminClusterCreate, + Read: resourceGkeonpremBareMetalAdminClusterRead, + Update: resourceGkeonpremBareMetalAdminClusterUpdate, + Delete: resourceGkeonpremBareMetalAdminClusterDelete, + + Importer: &schema.ResourceImporter{ + State: resourceGkeonpremBareMetalAdminClusterImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(60 * time.Minute), + Update: schema.DefaultTimeout(60 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + CustomizeDiff: customdiff.All( + tpgresource.SetAnnotationsDiff, + tpgresource.DefaultProviderProject, + ), + + Schema: map[string]*schema.Schema{ + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The location of the resource.`, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The bare metal admin cluster name.`, + }, + "annotations": { + Type: schema.TypeMap, + Optional: true, + Description: `Annotations on the Bare Metal Admin Cluster. +This field has the same restrictions as Kubernetes annotations. +The total size of all keys and values combined is limited to 256k. +Key can have 2 segments: prefix (optional) and name (required), +separated by a slash (/). +Prefix must be a DNS subdomain. +Name must be 63 characters or less, begin and end with alphanumerics, +with dashes (-), underscores (_), dots (.), and alphanumerics between. + + +**Note**: This field is non-authoritative, and will only manage the annotations present in your configuration. +Please refer to the field 'effective_annotations' for all of the annotations present on the resource.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "bare_metal_version": { + Type: schema.TypeString, + Optional: true, + Description: `A human readable description of this Bare Metal Admin Cluster.`, + }, + "cluster_operations": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the Admin Cluster's observability infrastructure.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enable_application_logs": { + Type: schema.TypeBool, + Optional: true, + Description: `Whether collection of application logs/metrics should be enabled (in addition to system logs/metrics).`, + }, + }, + }, + }, + "control_plane": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the control plane configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "control_plane_node_pool_config": { + Type: schema.TypeList, + Required: true, + Description: `Configures the node pool running the control plane. If specified the corresponding NodePool will be created for the cluster's control plane. The NodePool will have the same name and namespace as the cluster.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_pool_config": { + Type: schema.TypeList, + Required: true, + Description: `The generic configuration for a node pool running the control plane.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "labels": { + Type: schema.TypeMap, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to +each node. These will added in addition to any default label(s) +that Kubernetes may apply to the node. In case of conflict in +label keys, the applied set may differ depending on the Kubernetes +version -- it's best to assume the behavior is undefined and +conflicts should be avoided. For more information, including usage +and the valid values, see: + http://kubernetes.io/v1.1/docs/user-guide/labels.html +An object containing a list of "key": value pairs. +Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "node_configs": { + Type: schema.TypeList, + Optional: true, + Description: `The list of machine addresses in the Bare Metal Node Pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "labels": { + Type: schema.TypeMap, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to +each node. These will added in addition to any default label(s) +that Kubernetes may apply to the node. In case of conflict in +label keys, the applied set may differ depending on the Kubernetes +version -- it's best to assume the behavior is undefined and +conflicts should be avoided. For more information, including usage +and the valid values, see: + http://kubernetes.io/v1.1/docs/user-guide/labels.html +An object containing a list of "key": value pairs. +Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "node_ip": { + Type: schema.TypeString, + Optional: true, + Description: `The default IPv4 address for SSH access and Kubernetes node. +Example: 192.168.0.1`, + }, + }, + }, + }, + "operating_system": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the nodes operating system (default: LINUX).`, + }, + "taints": { + Type: schema.TypeList, + Optional: true, + Description: `The initial taints assigned to nodes of this node pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "effect": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.ValidateEnum([]string{"EFFECT_UNSPECIFIED", "PREFER_NO_SCHEDULE", "NO_EXECUTE", ""}), + Description: `Specifies the nodes operating system (default: LINUX). Possible values: ["EFFECT_UNSPECIFIED", "PREFER_NO_SCHEDULE", "NO_EXECUTE"]`, + }, + "key": { + Type: schema.TypeString, + Optional: true, + Description: `Key associated with the effect.`, + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: `Value associated with the effect.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "api_server_args": { + Type: schema.TypeList, + Optional: true, + Description: `Customizes the default API server args. Only a subset of +customized flags are supported. Please refer to the API server +documentation below to know the exact format: +https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "argument": { + Type: schema.TypeString, + Required: true, + Description: `The argument name as it appears on the API Server command line please make sure to remove the leading dashes.`, + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: `The value of the arg as it will be passed to the API Server command line.`, + }, + }, + }, + }, + }, + }, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: `A human readable description of this Bare Metal Admin Cluster.`, + }, + "load_balancer": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the load balancer configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "port_config": { + Type: schema.TypeList, + Required: true, + Description: `Specifies the load balancer ports.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "control_plane_load_balancer_port": { + Type: schema.TypeInt, + Required: true, + Description: `The port that control plane hosted load balancers will listen on.`, + }, + }, + }, + }, + "vip_config": { + Type: schema.TypeList, + Required: true, + Description: `Specified the Bare Metal Load Balancer Config`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "control_plane_vip": { + Type: schema.TypeString, + Required: true, + Description: `The VIP which you previously set aside for the Kubernetes API of this Bare Metal Admin Cluster.`, + }, + }, + }, + }, + "manual_lb_config": { + Type: schema.TypeList, + Optional: true, + Description: `A nested object resource`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + Description: `Whether manual load balancing is enabled.`, + }, + }, + }, + }, + }, + }, + }, + "maintenance_config": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the workload node configurations.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "maintenance_address_cidr_blocks": { + Type: schema.TypeList, + Required: true, + Description: `All IPv4 address from these ranges will be placed into maintenance mode. +Nodes in maintenance mode will be cordoned and drained. When both of these +are true, the "baremetal.cluster.gke.io/maintenance" annotation will be set +on the node resource.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "network_config": { + Type: schema.TypeList, + Optional: true, + Description: `Network configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "island_mode_cidr": { + Type: schema.TypeList, + Optional: true, + Description: `A nested object resource`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pod_address_cidr_blocks": { + Type: schema.TypeList, + Required: true, + Description: `All pods in the cluster are assigned an RFC1918 IPv4 address from these ranges. This field cannot be changed after creation.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "service_address_cidr_blocks": { + Type: schema.TypeList, + Required: true, + Description: `All services in the cluster are assigned an RFC1918 IPv4 address from these ranges. This field cannot be changed after creation.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + ExactlyOneOf: []string{"network_config.0.island_mode_cidr"}, + }, + }, + }, + }, + "node_access_config": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the node access related settings for the bare metal user cluster.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "login_user": { + Type: schema.TypeString, + Optional: true, + Description: `LoginUser is the user name used to access node machines. +It defaults to "root" if not set.`, + }, + }, + }, + }, + "node_config": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the workload node configurations.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "max_pods_per_node": { + Type: schema.TypeInt, + Optional: true, + Description: `The maximum number of pods a node can run. The size of the CIDR range +assigned to the node will be derived from this parameter.`, + }, + }, + }, + }, + "proxy": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the cluster proxy configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uri": { + Type: schema.TypeString, + Required: true, + Description: `Specifies the address of your proxy server. +Examples: http://domain +WARNING: Do not provide credentials in the format +http://(username:password@)domain these will be rejected by the server.`, + }, + "no_proxy": { + Type: schema.TypeList, + Optional: true, + Description: `A list of IPs, hostnames, and domains that should skip the proxy. +Examples: ["127.0.0.1", "example.com", ".corp", "localhost"].`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "security_config": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the security related settings for the Bare Metal User Cluster.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorization": { + Type: schema.TypeList, + Optional: true, + Description: `Configures user access to the Bare Metal User cluster.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "admin_users": { + Type: schema.TypeList, + Required: true, + Description: `Users that will be granted the cluster-admin role on the cluster, providing full access to the cluster.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + Description: `The name of the user, e.g. 'my-gcp-id@gmail.com'.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "storage": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the cluster storage configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "lvp_node_mounts_config": { + Type: schema.TypeList, + Required: true, + Description: `Specifies the config for local PersistentVolumes backed +by mounted node disks. These disks need to be formatted and mounted by the +user, which can be done before or after cluster creation.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "path": { + Type: schema.TypeString, + Required: true, + Description: `The host machine path.`, + }, + "storage_class": { + Type: schema.TypeString, + Required: true, + Description: `The StorageClass name that PVs will be created with.`, + }, + }, + }, + }, + "lvp_share_config": { + Type: schema.TypeList, + Required: true, + Description: `Specifies the config for local PersistentVolumes backed by +subdirectories in a shared filesystem. These subdirectores are +automatically created during cluster creation.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "lvp_config": { + Type: schema.TypeList, + Required: true, + Description: `Defines the machine path and storage class for the LVP Share.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "path": { + Type: schema.TypeString, + Required: true, + Description: `The host machine path.`, + }, + "storage_class": { + Type: schema.TypeString, + Required: true, + Description: `The StorageClass name that PVs will be created with.`, + }, + }, + }, + }, + "shared_path_pv_count": { + Type: schema.TypeInt, + Optional: true, + Description: `The number of subdirectories to create under path.`, + }, + }, + }, + }, + }, + }, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was created, in RFC3339 text format.`, + }, + "delete_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was deleted, in RFC3339 text format.`, + }, + "effective_annotations": { + Type: schema.TypeMap, + Computed: true, + Description: `All of annotations (key/value pairs) present on the resource in GCP, including the annotations configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "endpoint": { + Type: schema.TypeString, + Computed: true, + Description: `The IP address name of Bare Metal Admin Cluster's API server.`, + }, + "etag": { + Type: schema.TypeString, + Computed: true, + Description: `This checksum is computed by the server based on the value of other +fields, and may be sent on update and delete requests to ensure the +client has an up-to-date value before proceeding. +Allows clients to perform consistent read-modify-writes +through optimistic concurrency control.`, + }, + "fleet": { + Type: schema.TypeList, + Computed: true, + Description: `Fleet related configuration. +Fleets are a Google Cloud concept for logically organizing clusters, +letting you use and manage multi-cluster capabilities and apply +consistent policies across your systems. +See [Anthos Fleets](https://cloud.google.com/anthos/multicluster-management/fleets) for +more details on Anthos multi-cluster capabilities using Fleets.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "membership": { + Type: schema.TypeString, + Computed: true, + Description: `The name of the managed Hub Membership resource associated to this cluster. +Membership names are formatted as +'projects//locations//memberships/'.`, + }, + }, + }, + }, + "local_name": { + Type: schema.TypeString, + Computed: true, + Description: `The object name of the Bare Metal Admin Cluster custom resource on the +associated admin cluster. This field is used to support conflicting +names when enrolling existing clusters to the API. When used as a part of +cluster enrollment, this field will differ from the ID in the resource +name. For new clusters, this field will match the user provided cluster ID +and be visible in the last component of the resource name. It is not +modifiable. +All users should use this name to access their cluster using gkectl or +kubectl and should expect to see the local name when viewing admin +cluster controller logs.`, + }, + "reconciling": { + Type: schema.TypeBool, + Computed: true, + Description: `If set, there are currently changes in flight to the Bare Metal Admin Cluster.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The current state of this cluster.`, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Description: `Specifies detailed cluster status.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "conditions": { + Type: schema.TypeList, + Computed: true, + Description: `ResourceConditions provide a standard mechanism for higher-level status reporting from admin cluster controller.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "message": { + Type: schema.TypeString, + Optional: true, + Description: `Human-readable message indicating details about last transition.`, + }, + "reason": { + Type: schema.TypeString, + Optional: true, + Description: `Machine-readable message indicating details about last transition.`, + }, + "type": { + Type: schema.TypeString, + Optional: true, + Description: `Type of the condition. +(e.g., ClusterRunning, NodePoolRunning or ServerSidePreflightReady)`, + }, + "last_transition_time": { + Type: schema.TypeString, + Computed: true, + Description: `Last time the condition transit from one status to another.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The lifecycle state of the condition.`, + }, + }, + }, + }, + "error_message": { + Type: schema.TypeString, + Computed: true, + Description: `Human-friendly representation of the error message from the admin cluster +controller. The error message can be temporary as the admin cluster +controller creates a cluster or node pool. If the error message persists +for a longer period of time, it can be used to surface error message to +indicate real problems requiring user intervention.`, + }, + }, + }, + }, + "uid": { + Type: schema.TypeString, + Computed: true, + Description: `The unique identifier of the Bare Metal Admin Cluster.`, + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was last updated, in RFC3339 text format.`, + }, + "validation_check": { + Type: schema.TypeList, + Computed: true, + Description: `Specifies the security related settings for the Bare Metal Admin Cluster.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "options": { + Type: schema.TypeString, + Computed: true, + Description: `Options used for the validation check.`, + }, + "scenario": { + Type: schema.TypeString, + Computed: true, + Description: `The scenario when the preflight checks were run..`, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Description: `Specifies the detailed validation check status`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "result": { + Type: schema.TypeList, + Computed: true, + Description: `Individual checks which failed as part of the Preflight check execution.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "category": { + Type: schema.TypeString, + Computed: true, + Description: `The category of the validation.`, + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: `The description of the validation check.`, + }, + "details": { + Type: schema.TypeString, + Computed: true, + Description: `Detailed failure information, which might be unformatted.`, + }, + "options": { + Type: schema.TypeString, + Computed: true, + Description: `Options used for the validation check.`, + }, + "reason": { + Type: schema.TypeString, + Computed: true, + Description: `A human-readable message of the check failure.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + UseJSONNumber: true, + } +} + +func resourceGkeonpremBareMetalAdminClusterCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + descriptionProp, err := expandGkeonpremBareMetalAdminClusterDescription(d.Get("description"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + bareMetalVersionProp, err := expandGkeonpremBareMetalAdminClusterBareMetalVersion(d.Get("bare_metal_version"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("bare_metal_version"); !tpgresource.IsEmptyValue(reflect.ValueOf(bareMetalVersionProp)) && (ok || !reflect.DeepEqual(v, bareMetalVersionProp)) { + obj["bareMetalVersion"] = bareMetalVersionProp + } + networkConfigProp, err := expandGkeonpremBareMetalAdminClusterNetworkConfig(d.Get("network_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("network_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(networkConfigProp)) && (ok || !reflect.DeepEqual(v, networkConfigProp)) { + obj["networkConfig"] = networkConfigProp + } + controlPlaneProp, err := expandGkeonpremBareMetalAdminClusterControlPlane(d.Get("control_plane"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("control_plane"); !tpgresource.IsEmptyValue(reflect.ValueOf(controlPlaneProp)) && (ok || !reflect.DeepEqual(v, controlPlaneProp)) { + obj["controlPlane"] = controlPlaneProp + } + loadBalancerProp, err := expandGkeonpremBareMetalAdminClusterLoadBalancer(d.Get("load_balancer"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("load_balancer"); !tpgresource.IsEmptyValue(reflect.ValueOf(loadBalancerProp)) && (ok || !reflect.DeepEqual(v, loadBalancerProp)) { + obj["loadBalancer"] = loadBalancerProp + } + storageProp, err := expandGkeonpremBareMetalAdminClusterStorage(d.Get("storage"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("storage"); !tpgresource.IsEmptyValue(reflect.ValueOf(storageProp)) && (ok || !reflect.DeepEqual(v, storageProp)) { + obj["storage"] = storageProp + } + proxyProp, err := expandGkeonpremBareMetalAdminClusterProxy(d.Get("proxy"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("proxy"); !tpgresource.IsEmptyValue(reflect.ValueOf(proxyProp)) && (ok || !reflect.DeepEqual(v, proxyProp)) { + obj["proxy"] = proxyProp + } + clusterOperationsProp, err := expandGkeonpremBareMetalAdminClusterClusterOperations(d.Get("cluster_operations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("cluster_operations"); !tpgresource.IsEmptyValue(reflect.ValueOf(clusterOperationsProp)) && (ok || !reflect.DeepEqual(v, clusterOperationsProp)) { + obj["clusterOperations"] = clusterOperationsProp + } + maintenanceConfigProp, err := expandGkeonpremBareMetalAdminClusterMaintenanceConfig(d.Get("maintenance_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("maintenance_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(maintenanceConfigProp)) && (ok || !reflect.DeepEqual(v, maintenanceConfigProp)) { + obj["maintenanceConfig"] = maintenanceConfigProp + } + nodeConfigProp, err := expandGkeonpremBareMetalAdminClusterNodeConfig(d.Get("node_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(nodeConfigProp)) && (ok || !reflect.DeepEqual(v, nodeConfigProp)) { + obj["nodeConfig"] = nodeConfigProp + } + nodeAccessConfigProp, err := expandGkeonpremBareMetalAdminClusterNodeAccessConfig(d.Get("node_access_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_access_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(nodeAccessConfigProp)) && (ok || !reflect.DeepEqual(v, nodeAccessConfigProp)) { + obj["nodeAccessConfig"] = nodeAccessConfigProp + } + securityConfigProp, err := expandGkeonpremBareMetalAdminClusterSecurityConfig(d.Get("security_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("security_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(securityConfigProp)) && (ok || !reflect.DeepEqual(v, securityConfigProp)) { + obj["securityConfig"] = securityConfigProp + } + annotationsProp, err := expandGkeonpremBareMetalAdminClusterEffectiveAnnotations(d.Get("effective_annotations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_annotations"); !tpgresource.IsEmptyValue(reflect.ValueOf(annotationsProp)) && (ok || !reflect.DeepEqual(v, annotationsProp)) { + obj["annotations"] = annotationsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalAdminClusters?bare_metal_admin_cluster_id={{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new BareMetalAdminCluster: %#v", obj) + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalAdminCluster: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "POST", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutCreate), + }) + if err != nil { + return fmt.Errorf("Error creating BareMetalAdminCluster: %s", err) + } + + // Store the ID now + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/bareMetalAdminClusters/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + // Use the resource in the operation response to populate + // identity fields and d.Id() before read + var opRes map[string]interface{} + err = GkeonpremOperationWaitTimeWithResponse( + config, res, &opRes, project, "Creating BareMetalAdminCluster", userAgent, + d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error waiting to create BareMetalAdminCluster: %s", err) + } + + // This may have caused the ID to update - update it if so. + id, err = tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/bareMetalAdminClusters/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating BareMetalAdminCluster %q: %#v", d.Id(), res) + + return resourceGkeonpremBareMetalAdminClusterRead(d, meta) +} + +func resourceGkeonpremBareMetalAdminClusterRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalAdminClusters/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalAdminCluster: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("GkeonpremBareMetalAdminCluster %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + + if err := d.Set("description", flattenGkeonpremBareMetalAdminClusterDescription(res["description"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("bare_metal_version", flattenGkeonpremBareMetalAdminClusterBareMetalVersion(res["bareMetalVersion"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("uid", flattenGkeonpremBareMetalAdminClusterUid(res["uid"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("state", flattenGkeonpremBareMetalAdminClusterState(res["state"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("endpoint", flattenGkeonpremBareMetalAdminClusterEndpoint(res["endpoint"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("reconciling", flattenGkeonpremBareMetalAdminClusterReconciling(res["reconciling"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("create_time", flattenGkeonpremBareMetalAdminClusterCreateTime(res["createTime"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("update_time", flattenGkeonpremBareMetalAdminClusterUpdateTime(res["updateTime"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("delete_time", flattenGkeonpremBareMetalAdminClusterDeleteTime(res["deleteTime"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("local_name", flattenGkeonpremBareMetalAdminClusterLocalName(res["localName"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("etag", flattenGkeonpremBareMetalAdminClusterEtag(res["etag"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("annotations", flattenGkeonpremBareMetalAdminClusterAnnotations(res["annotations"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("network_config", flattenGkeonpremBareMetalAdminClusterNetworkConfig(res["networkConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("control_plane", flattenGkeonpremBareMetalAdminClusterControlPlane(res["controlPlane"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("load_balancer", flattenGkeonpremBareMetalAdminClusterLoadBalancer(res["loadBalancer"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("storage", flattenGkeonpremBareMetalAdminClusterStorage(res["storage"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("proxy", flattenGkeonpremBareMetalAdminClusterProxy(res["proxy"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("cluster_operations", flattenGkeonpremBareMetalAdminClusterClusterOperations(res["clusterOperations"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("maintenance_config", flattenGkeonpremBareMetalAdminClusterMaintenanceConfig(res["maintenanceConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("node_config", flattenGkeonpremBareMetalAdminClusterNodeConfig(res["nodeConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("fleet", flattenGkeonpremBareMetalAdminClusterFleet(res["fleet"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("status", flattenGkeonpremBareMetalAdminClusterStatus(res["status"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("validation_check", flattenGkeonpremBareMetalAdminClusterValidationCheck(res["validationCheck"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("node_access_config", flattenGkeonpremBareMetalAdminClusterNodeAccessConfig(res["nodeAccessConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("security_config", flattenGkeonpremBareMetalAdminClusterSecurityConfig(res["securityConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + if err := d.Set("effective_annotations", flattenGkeonpremBareMetalAdminClusterEffectiveAnnotations(res["annotations"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalAdminCluster: %s", err) + } + + return nil +} + +func resourceGkeonpremBareMetalAdminClusterUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalAdminCluster: %s", err) + } + billingProject = project + + obj := make(map[string]interface{}) + descriptionProp, err := expandGkeonpremBareMetalAdminClusterDescription(d.Get("description"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + bareMetalVersionProp, err := expandGkeonpremBareMetalAdminClusterBareMetalVersion(d.Get("bare_metal_version"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("bare_metal_version"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, bareMetalVersionProp)) { + obj["bareMetalVersion"] = bareMetalVersionProp + } + networkConfigProp, err := expandGkeonpremBareMetalAdminClusterNetworkConfig(d.Get("network_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("network_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, networkConfigProp)) { + obj["networkConfig"] = networkConfigProp + } + controlPlaneProp, err := expandGkeonpremBareMetalAdminClusterControlPlane(d.Get("control_plane"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("control_plane"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, controlPlaneProp)) { + obj["controlPlane"] = controlPlaneProp + } + loadBalancerProp, err := expandGkeonpremBareMetalAdminClusterLoadBalancer(d.Get("load_balancer"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("load_balancer"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, loadBalancerProp)) { + obj["loadBalancer"] = loadBalancerProp + } + storageProp, err := expandGkeonpremBareMetalAdminClusterStorage(d.Get("storage"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("storage"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, storageProp)) { + obj["storage"] = storageProp + } + proxyProp, err := expandGkeonpremBareMetalAdminClusterProxy(d.Get("proxy"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("proxy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, proxyProp)) { + obj["proxy"] = proxyProp + } + clusterOperationsProp, err := expandGkeonpremBareMetalAdminClusterClusterOperations(d.Get("cluster_operations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("cluster_operations"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clusterOperationsProp)) { + obj["clusterOperations"] = clusterOperationsProp + } + maintenanceConfigProp, err := expandGkeonpremBareMetalAdminClusterMaintenanceConfig(d.Get("maintenance_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("maintenance_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, maintenanceConfigProp)) { + obj["maintenanceConfig"] = maintenanceConfigProp + } + nodeConfigProp, err := expandGkeonpremBareMetalAdminClusterNodeConfig(d.Get("node_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nodeConfigProp)) { + obj["nodeConfig"] = nodeConfigProp + } + nodeAccessConfigProp, err := expandGkeonpremBareMetalAdminClusterNodeAccessConfig(d.Get("node_access_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_access_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nodeAccessConfigProp)) { + obj["nodeAccessConfig"] = nodeAccessConfigProp + } + securityConfigProp, err := expandGkeonpremBareMetalAdminClusterSecurityConfig(d.Get("security_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("security_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, securityConfigProp)) { + obj["securityConfig"] = securityConfigProp + } + annotationsProp, err := expandGkeonpremBareMetalAdminClusterEffectiveAnnotations(d.Get("effective_annotations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_annotations"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, annotationsProp)) { + obj["annotations"] = annotationsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalAdminClusters/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating BareMetalAdminCluster %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("description") { + updateMask = append(updateMask, "description") + } + + if d.HasChange("bare_metal_version") { + updateMask = append(updateMask, "bareMetalVersion") + } + + if d.HasChange("network_config") { + updateMask = append(updateMask, "networkConfig") + } + + if d.HasChange("control_plane") { + updateMask = append(updateMask, "controlPlane") + } + + if d.HasChange("load_balancer") { + updateMask = append(updateMask, "loadBalancer") + } + + if d.HasChange("storage") { + updateMask = append(updateMask, "storage") + } + + if d.HasChange("proxy") { + updateMask = append(updateMask, "proxy") + } + + if d.HasChange("cluster_operations") { + updateMask = append(updateMask, "clusterOperations") + } + + if d.HasChange("maintenance_config") { + updateMask = append(updateMask, "maintenanceConfig") + } + + if d.HasChange("node_config") { + updateMask = append(updateMask, "nodeConfig") + } + + if d.HasChange("node_access_config") { + updateMask = append(updateMask, "nodeAccessConfig") + } + + if d.HasChange("security_config") { + updateMask = append(updateMask, "securityConfig") + } + + if d.HasChange("effective_annotations") { + updateMask = append(updateMask, "annotations") + } + // updateMask is a URL parameter but not present in the schema, so ReplaceVars + // won't set it + url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + // if updateMask is empty we are not updating anything so skip the post + if len(updateMask) > 0 { + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "PATCH", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutUpdate), + }) + + if err != nil { + return fmt.Errorf("Error updating BareMetalAdminCluster %q: %s", d.Id(), err) + } else { + log.Printf("[DEBUG] Finished updating BareMetalAdminCluster %q: %#v", d.Id(), res) + } + + err = GkeonpremOperationWaitTime( + config, res, project, "Updating BareMetalAdminCluster", userAgent, + d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return err + } + } + + return resourceGkeonpremBareMetalAdminClusterRead(d, meta) +} + +func resourceGkeonpremBareMetalAdminClusterDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[WARNING] Gkeonprem BareMetalAdminCluster resources"+ + " cannot be deleted from Google Cloud. The resource %s will be removed from Terraform"+ + " state, but will still be present on Google Cloud.", d.Id()) + d.SetId("") + + return nil +} + +func resourceGkeonpremBareMetalAdminClusterImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*transport_tpg.Config) + if err := tpgresource.ParseImportId([]string{ + "^projects/(?P[^/]+)/locations/(?P[^/]+)/bareMetalAdminClusters/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)$", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/bareMetalAdminClusters/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenGkeonpremBareMetalAdminClusterDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterBareMetalVersion(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterUid(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterEndpoint(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterReconciling(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterUpdateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterDeleteTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterLocalName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterEtag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("annotations"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenGkeonpremBareMetalAdminClusterNetworkConfig(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["island_mode_cidr"] = + flattenGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidr(original["islandModeCidr"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidr(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["service_address_cidr_blocks"] = + flattenGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidrServiceAddressCidrBlocks(original["serviceAddressCidrBlocks"], d, config) + transformed["pod_address_cidr_blocks"] = + flattenGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidrPodAddressCidrBlocks(original["podAddressCidrBlocks"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidrServiceAddressCidrBlocks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidrPodAddressCidrBlocks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterControlPlane(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["control_plane_node_pool_config"] = + flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfig(original["controlPlaneNodePoolConfig"], d, config) + transformed["api_server_args"] = + flattenGkeonpremBareMetalAdminClusterControlPlaneApiServerArgs(original["apiServerArgs"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfig(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["node_pool_config"] = + flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfig(original["nodePoolConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfig(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["node_configs"] = + flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigs(original["nodeConfigs"], d, config) + transformed["operating_system"] = + flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigOperatingSystem(original["operatingSystem"], d, config) + transformed["taints"] = + flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaints(original["taints"], d, config) + transformed["labels"] = + flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigLabels(original["labels"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigs(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{}{ + "node_ip": flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsNodeIp(original["nodeIp"], d, config), + "labels": flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsLabels(original["labels"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsNodeIp(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigOperatingSystem(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaints(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{}{ + "key": flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsKey(original["key"], d, config), + "value": flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsValue(original["value"], d, config), + "effect": flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsEffect(original["effect"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsValue(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsEffect(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterControlPlaneApiServerArgs(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{}{ + "argument": flattenGkeonpremBareMetalAdminClusterControlPlaneApiServerArgsArgument(original["argument"], d, config), + "value": flattenGkeonpremBareMetalAdminClusterControlPlaneApiServerArgsValue(original["value"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalAdminClusterControlPlaneApiServerArgsArgument(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterControlPlaneApiServerArgsValue(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterLoadBalancer(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["vip_config"] = + flattenGkeonpremBareMetalAdminClusterLoadBalancerVipConfig(original["vipConfig"], d, config) + transformed["port_config"] = + flattenGkeonpremBareMetalAdminClusterLoadBalancerPortConfig(original["portConfig"], d, config) + transformed["manual_lb_config"] = + flattenGkeonpremBareMetalAdminClusterLoadBalancerManualLbConfig(original["manualLbConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterLoadBalancerVipConfig(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["control_plane_vip"] = + flattenGkeonpremBareMetalAdminClusterLoadBalancerVipConfigControlPlaneVip(original["controlPlaneVip"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterLoadBalancerVipConfigControlPlaneVip(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterLoadBalancerPortConfig(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["control_plane_load_balancer_port"] = + flattenGkeonpremBareMetalAdminClusterLoadBalancerPortConfigControlPlaneLoadBalancerPort(original["controlPlaneLoadBalancerPort"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterLoadBalancerPortConfigControlPlaneLoadBalancerPort(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 flattenGkeonpremBareMetalAdminClusterLoadBalancerManualLbConfig(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["enabled"] = + flattenGkeonpremBareMetalAdminClusterLoadBalancerManualLbConfigEnabled(original["enabled"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterLoadBalancerManualLbConfigEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterStorage(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["lvp_share_config"] = + flattenGkeonpremBareMetalAdminClusterStorageLvpShareConfig(original["lvpShareConfig"], d, config) + transformed["lvp_node_mounts_config"] = + flattenGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfig(original["lvpNodeMountsConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterStorageLvpShareConfig(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["lvp_config"] = + flattenGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfig(original["lvpConfig"], d, config) + transformed["shared_path_pv_count"] = + flattenGkeonpremBareMetalAdminClusterStorageLvpShareConfigSharedPathPvCount(original["sharedPathPvCount"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfig(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["path"] = + flattenGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfigPath(original["path"], d, config) + transformed["storage_class"] = + flattenGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfigStorageClass(original["storageClass"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfigPath(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfigStorageClass(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterStorageLvpShareConfigSharedPathPvCount(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 flattenGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfig(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["path"] = + flattenGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfigPath(original["path"], d, config) + transformed["storage_class"] = + flattenGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfigStorageClass(original["storageClass"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfigPath(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfigStorageClass(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterProxy(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["uri"] = + flattenGkeonpremBareMetalAdminClusterProxyUri(original["uri"], d, config) + transformed["no_proxy"] = + flattenGkeonpremBareMetalAdminClusterProxyNoProxy(original["noProxy"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterProxyUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterProxyNoProxy(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterClusterOperations(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["enable_application_logs"] = + flattenGkeonpremBareMetalAdminClusterClusterOperationsEnableApplicationLogs(original["enableApplicationLogs"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterClusterOperationsEnableApplicationLogs(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterMaintenanceConfig(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["maintenance_address_cidr_blocks"] = + flattenGkeonpremBareMetalAdminClusterMaintenanceConfigMaintenanceAddressCidrBlocks(original["maintenanceAddressCidrBlocks"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterMaintenanceConfigMaintenanceAddressCidrBlocks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterNodeConfig(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_pods_per_node"] = + flattenGkeonpremBareMetalAdminClusterNodeConfigMaxPodsPerNode(original["maxPodsPerNode"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterNodeConfigMaxPodsPerNode(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 flattenGkeonpremBareMetalAdminClusterFleet(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["membership"] = + flattenGkeonpremBareMetalAdminClusterFleetMembership(original["membership"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterFleetMembership(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterStatus(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["error_message"] = + flattenGkeonpremBareMetalAdminClusterStatusErrorMessage(original["errorMessage"], d, config) + transformed["conditions"] = + flattenGkeonpremBareMetalAdminClusterStatusConditions(original["conditions"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterStatusErrorMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterStatusConditions(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{}{ + "type": flattenGkeonpremBareMetalAdminClusterStatusConditionsType(original["type"], d, config), + "reason": flattenGkeonpremBareMetalAdminClusterStatusConditionsReason(original["reason"], d, config), + "message": flattenGkeonpremBareMetalAdminClusterStatusConditionsMessage(original["message"], d, config), + "last_transition_time": flattenGkeonpremBareMetalAdminClusterStatusConditionsLastTransitionTime(original["lastTransitionTime"], d, config), + "state": flattenGkeonpremBareMetalAdminClusterStatusConditionsState(original["state"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalAdminClusterStatusConditionsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterStatusConditionsReason(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterStatusConditionsMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterStatusConditionsLastTransitionTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterStatusConditionsState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterValidationCheck(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["options"] = + flattenGkeonpremBareMetalAdminClusterValidationCheckOptions(original["options"], d, config) + transformed["status"] = + flattenGkeonpremBareMetalAdminClusterValidationCheckStatus(original["status"], d, config) + transformed["scenario"] = + flattenGkeonpremBareMetalAdminClusterValidationCheckScenario(original["scenario"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterValidationCheckOptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterValidationCheckStatus(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["result"] = + flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResult(original["result"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResult(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{}{ + "options": flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResultOptions(original["options"], d, config), + "description": flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResultDescription(original["description"], d, config), + "category": flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResultCategory(original["category"], d, config), + "reason": flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResultReason(original["reason"], d, config), + "details": flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResultDetails(original["details"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResultOptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResultDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResultCategory(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResultReason(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterValidationCheckStatusResultDetails(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterValidationCheckScenario(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterNodeAccessConfig(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["login_user"] = + flattenGkeonpremBareMetalAdminClusterNodeAccessConfigLoginUser(original["loginUser"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterNodeAccessConfigLoginUser(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterSecurityConfig(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["authorization"] = + flattenGkeonpremBareMetalAdminClusterSecurityConfigAuthorization(original["authorization"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterSecurityConfigAuthorization(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["admin_users"] = + flattenGkeonpremBareMetalAdminClusterSecurityConfigAuthorizationAdminUsers(original["adminUsers"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalAdminClusterSecurityConfigAuthorizationAdminUsers(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{}{ + "username": flattenGkeonpremBareMetalAdminClusterSecurityConfigAuthorizationAdminUsersUsername(original["username"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalAdminClusterSecurityConfigAuthorizationAdminUsersUsername(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalAdminClusterEffectiveAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandGkeonpremBareMetalAdminClusterDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterBareMetalVersion(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterNetworkConfig(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{}) + + transformedIslandModeCidr, err := expandGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidr(original["island_mode_cidr"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIslandModeCidr); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["islandModeCidr"] = transformedIslandModeCidr + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidr(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{}) + + transformedServiceAddressCidrBlocks, err := expandGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidrServiceAddressCidrBlocks(original["service_address_cidr_blocks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedServiceAddressCidrBlocks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["serviceAddressCidrBlocks"] = transformedServiceAddressCidrBlocks + } + + transformedPodAddressCidrBlocks, err := expandGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidrPodAddressCidrBlocks(original["pod_address_cidr_blocks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPodAddressCidrBlocks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["podAddressCidrBlocks"] = transformedPodAddressCidrBlocks + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidrServiceAddressCidrBlocks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterNetworkConfigIslandModeCidrPodAddressCidrBlocks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlane(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{}) + + transformedControlPlaneNodePoolConfig, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfig(original["control_plane_node_pool_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneNodePoolConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneNodePoolConfig"] = transformedControlPlaneNodePoolConfig + } + + transformedApiServerArgs, err := expandGkeonpremBareMetalAdminClusterControlPlaneApiServerArgs(original["api_server_args"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedApiServerArgs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["apiServerArgs"] = transformedApiServerArgs + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfig(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{}) + + transformedNodePoolConfig, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfig(original["node_pool_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodePoolConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodePoolConfig"] = transformedNodePoolConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfig(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{}) + + transformedNodeConfigs, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigs(original["node_configs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodeConfigs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodeConfigs"] = transformedNodeConfigs + } + + transformedOperatingSystem, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigOperatingSystem(original["operating_system"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOperatingSystem); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["operatingSystem"] = transformedOperatingSystem + } + + transformedTaints, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaints(original["taints"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTaints); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["taints"] = transformedTaints + } + + transformedLabels, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigs(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{}) + + transformedNodeIp, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsNodeIp(original["node_ip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodeIp); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodeIp"] = transformedNodeIp + } + + transformedLabels, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsNodeIp(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigOperatingSystem(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaints(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{}) + + transformedKey, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedValue, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["value"] = transformedValue + } + + transformedEffect, err := expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsEffect(original["effect"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEffect); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["effect"] = transformedEffect + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsValue(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsEffect(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneApiServerArgs(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{}) + + transformedArgument, err := expandGkeonpremBareMetalAdminClusterControlPlaneApiServerArgsArgument(original["argument"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedArgument); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["argument"] = transformedArgument + } + + transformedValue, err := expandGkeonpremBareMetalAdminClusterControlPlaneApiServerArgsValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["value"] = transformedValue + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneApiServerArgsArgument(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterControlPlaneApiServerArgsValue(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterLoadBalancer(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{}) + + transformedVipConfig, err := expandGkeonpremBareMetalAdminClusterLoadBalancerVipConfig(original["vip_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVipConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vipConfig"] = transformedVipConfig + } + + transformedPortConfig, err := expandGkeonpremBareMetalAdminClusterLoadBalancerPortConfig(original["port_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPortConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["portConfig"] = transformedPortConfig + } + + transformedManualLbConfig, err := expandGkeonpremBareMetalAdminClusterLoadBalancerManualLbConfig(original["manual_lb_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedManualLbConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["manualLbConfig"] = transformedManualLbConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterLoadBalancerVipConfig(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{}) + + transformedControlPlaneVip, err := expandGkeonpremBareMetalAdminClusterLoadBalancerVipConfigControlPlaneVip(original["control_plane_vip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneVip); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneVip"] = transformedControlPlaneVip + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterLoadBalancerVipConfigControlPlaneVip(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterLoadBalancerPortConfig(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{}) + + transformedControlPlaneLoadBalancerPort, err := expandGkeonpremBareMetalAdminClusterLoadBalancerPortConfigControlPlaneLoadBalancerPort(original["control_plane_load_balancer_port"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneLoadBalancerPort); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneLoadBalancerPort"] = transformedControlPlaneLoadBalancerPort + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterLoadBalancerPortConfigControlPlaneLoadBalancerPort(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterLoadBalancerManualLbConfig(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{}) + + transformedEnabled, err := expandGkeonpremBareMetalAdminClusterLoadBalancerManualLbConfigEnabled(original["enabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["enabled"] = transformedEnabled + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterLoadBalancerManualLbConfigEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterStorage(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{}) + + transformedLvpShareConfig, err := expandGkeonpremBareMetalAdminClusterStorageLvpShareConfig(original["lvp_share_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLvpShareConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["lvpShareConfig"] = transformedLvpShareConfig + } + + transformedLvpNodeMountsConfig, err := expandGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfig(original["lvp_node_mounts_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLvpNodeMountsConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["lvpNodeMountsConfig"] = transformedLvpNodeMountsConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterStorageLvpShareConfig(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{}) + + transformedLvpConfig, err := expandGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfig(original["lvp_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLvpConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["lvpConfig"] = transformedLvpConfig + } + + transformedSharedPathPvCount, err := expandGkeonpremBareMetalAdminClusterStorageLvpShareConfigSharedPathPvCount(original["shared_path_pv_count"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSharedPathPvCount); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["sharedPathPvCount"] = transformedSharedPathPvCount + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfig(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{}) + + transformedPath, err := expandGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfigPath(original["path"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPath); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["path"] = transformedPath + } + + transformedStorageClass, err := expandGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfigStorageClass(original["storage_class"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStorageClass); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["storageClass"] = transformedStorageClass + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfigPath(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterStorageLvpShareConfigLvpConfigStorageClass(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterStorageLvpShareConfigSharedPathPvCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfig(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{}) + + transformedPath, err := expandGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfigPath(original["path"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPath); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["path"] = transformedPath + } + + transformedStorageClass, err := expandGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfigStorageClass(original["storage_class"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStorageClass); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["storageClass"] = transformedStorageClass + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfigPath(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterStorageLvpNodeMountsConfigStorageClass(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterProxy(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{}) + + transformedUri, err := expandGkeonpremBareMetalAdminClusterProxyUri(original["uri"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUri); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["uri"] = transformedUri + } + + transformedNoProxy, err := expandGkeonpremBareMetalAdminClusterProxyNoProxy(original["no_proxy"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNoProxy); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["noProxy"] = transformedNoProxy + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterProxyUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterProxyNoProxy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterClusterOperations(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{}) + + transformedEnableApplicationLogs, err := expandGkeonpremBareMetalAdminClusterClusterOperationsEnableApplicationLogs(original["enable_application_logs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnableApplicationLogs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["enableApplicationLogs"] = transformedEnableApplicationLogs + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterClusterOperationsEnableApplicationLogs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterMaintenanceConfig(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{}) + + transformedMaintenanceAddressCidrBlocks, err := expandGkeonpremBareMetalAdminClusterMaintenanceConfigMaintenanceAddressCidrBlocks(original["maintenance_address_cidr_blocks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaintenanceAddressCidrBlocks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["maintenanceAddressCidrBlocks"] = transformedMaintenanceAddressCidrBlocks + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterMaintenanceConfigMaintenanceAddressCidrBlocks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterNodeConfig(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{}) + + transformedMaxPodsPerNode, err := expandGkeonpremBareMetalAdminClusterNodeConfigMaxPodsPerNode(original["max_pods_per_node"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxPodsPerNode); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["maxPodsPerNode"] = transformedMaxPodsPerNode + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterNodeConfigMaxPodsPerNode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterNodeAccessConfig(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{}) + + transformedLoginUser, err := expandGkeonpremBareMetalAdminClusterNodeAccessConfigLoginUser(original["login_user"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLoginUser); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["loginUser"] = transformedLoginUser + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterNodeAccessConfigLoginUser(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterSecurityConfig(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{}) + + transformedAuthorization, err := expandGkeonpremBareMetalAdminClusterSecurityConfigAuthorization(original["authorization"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAuthorization); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["authorization"] = transformedAuthorization + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterSecurityConfigAuthorization(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{}) + + transformedAdminUsers, err := expandGkeonpremBareMetalAdminClusterSecurityConfigAuthorizationAdminUsers(original["admin_users"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAdminUsers); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["adminUsers"] = transformedAdminUsers + } + + return transformed, nil +} + +func expandGkeonpremBareMetalAdminClusterSecurityConfigAuthorizationAdminUsers(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{}) + + transformedUsername, err := expandGkeonpremBareMetalAdminClusterSecurityConfigAuthorizationAdminUsersUsername(original["username"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUsername); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["username"] = transformedUsername + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalAdminClusterSecurityConfigAuthorizationAdminUsersUsername(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalAdminClusterEffectiveAnnotations(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} diff --git a/google/services/gkeonprem/resource_gkeonprem_bare_metal_admin_cluster_generated_test.go b/google/services/gkeonprem/resource_gkeonprem_bare_metal_admin_cluster_generated_test.go new file mode 100644 index 00000000000..295383bc376 --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_bare_metal_admin_cluster_generated_test.go @@ -0,0 +1,233 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccGkeonpremBareMetalAdminCluster_gkeonpremBareMetalAdminClusterBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalAdminCluster_gkeonpremBareMetalAdminClusterBasicExample(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_admin_cluster.admin-cluster-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremBareMetalAdminCluster_gkeonpremBareMetalAdminClusterBasicExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_bare_metal_admin_cluster" "admin-cluster-basic" { + name = "tf-test-my-cluster%{random_suffix}" + location = "us-west1" + bare_metal_version = "1.13.4" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/16"] + pod_address_cidr_blocks = ["10.240.0.0/13"] + } + } + node_config { + max_pods_per_node = 250 + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.2" + } + node_configs { + labels = {} + node_ip = "10.200.0.3" + } + node_configs { + labels = {} + node_ip = "10.200.0.4" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 443 + } + vip_config { + control_plane_vip = "10.200.0.5" + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 5 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + node_access_config { + login_user = "root" + } +} +`, context) +} + +func TestAccGkeonpremBareMetalAdminCluster_gkeonpremBareMetalAdminClusterFullExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalAdminCluster_gkeonpremBareMetalAdminClusterFullExample(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_admin_cluster.admin-cluster-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremBareMetalAdminCluster_gkeonpremBareMetalAdminClusterFullExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_bare_metal_admin_cluster" "admin-cluster-basic" { + name = "tf-test-my-cluster%{random_suffix}" + location = "us-west1" + description = "test description" + bare_metal_version = "1.13.4" + annotations = { + env = "test" + } + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/16"] + pod_address_cidr_blocks = ["10.240.0.0/13"] + } + } + node_config { + max_pods_per_node = 250 + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.2" + } + node_configs { + labels = {} + node_ip = "10.200.0.3" + } + node_configs { + labels = {} + node_ip = "10.200.0.4" + } + taints { + key = "test-key" + value = "test-value" + effect = "NO_EXECUTE" + } + } + } + api_server_args { + argument = "test argument" + value = "test value" + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 443 + } + vip_config { + control_plane_vip = "10.200.0.5" + } + manual_lb_config { + enabled = true + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 5 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + node_access_config { + login_user = "root" + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } + maintenance_config { + maintenance_address_cidr_blocks = ["10.0.0.1/32", "10.0.0.2/32"] + } + cluster_operations { + enable_application_logs = true + } + proxy { + uri = "test proxy uri" + no_proxy = ["127.0.0.1"] + } +} +`, context) +} diff --git a/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster.go b/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster.go new file mode 100644 index 00000000000..16007644b79 --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster.go @@ -0,0 +1,4593 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-provider-google/google/verify" +) + +func ResourceGkeonpremBareMetalCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceGkeonpremBareMetalClusterCreate, + Read: resourceGkeonpremBareMetalClusterRead, + Update: resourceGkeonpremBareMetalClusterUpdate, + Delete: resourceGkeonpremBareMetalClusterDelete, + + Importer: &schema.ResourceImporter{ + State: resourceGkeonpremBareMetalClusterImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(60 * time.Minute), + Update: schema.DefaultTimeout(60 * time.Minute), + Delete: schema.DefaultTimeout(60 * time.Minute), + }, + + CustomizeDiff: customdiff.All( + tpgresource.SetAnnotationsDiff, + tpgresource.DefaultProviderProject, + ), + + Schema: map[string]*schema.Schema{ + "admin_cluster_membership": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: tpgresource.ProjectNumberDiffSuppress, + Description: `The Admin Cluster this Bare Metal User Cluster belongs to. +This is the full resource name of the Admin Cluster's hub membership.`, + }, + "bare_metal_version": { + Type: schema.TypeString, + Required: true, + Description: `A human readable description of this Bare Metal User Cluster.`, + }, + "control_plane": { + Type: schema.TypeList, + Required: true, + Description: `Specifies the control plane configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "control_plane_node_pool_config": { + Type: schema.TypeList, + Required: true, + Description: `Configures the node pool running the control plane. If specified the corresponding NodePool will be created for the cluster's control plane. The NodePool will have the same name and namespace as the cluster.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_pool_config": { + Type: schema.TypeList, + Required: true, + Description: `The generic configuration for a node pool running the control plane.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "labels": { + Type: schema.TypeMap, + Computed: true, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to +each node. These will added in addition to any default label(s) +that Kubernetes may apply to the node. In case of conflict in +label keys, the applied set may differ depending on the Kubernetes +version -- it's best to assume the behavior is undefined and +conflicts should be avoided. For more information, including usage +and the valid values, see: + http://kubernetes.io/v1.1/docs/user-guide/labels.html +An object containing a list of "key": value pairs. +Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "node_configs": { + Type: schema.TypeList, + Optional: true, + Description: `The list of machine addresses in the Bare Metal Node Pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "labels": { + Type: schema.TypeMap, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to +each node. These will added in addition to any default label(s) +that Kubernetes may apply to the node. In case of conflict in +label keys, the applied set may differ depending on the Kubernetes +version -- it's best to assume the behavior is undefined and +conflicts should be avoided. For more information, including usage +and the valid values, see: + http://kubernetes.io/v1.1/docs/user-guide/labels.html +An object containing a list of "key": value pairs. +Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "node_ip": { + Type: schema.TypeString, + Optional: true, + Description: `The default IPv4 address for SSH access and Kubernetes node. +Example: 192.168.0.1`, + }, + }, + }, + }, + "operating_system": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the nodes operating system (default: LINUX).`, + Default: "LINUX", + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: `The initial taints assigned to nodes of this node pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "effect": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.ValidateEnum([]string{"EFFECT_UNSPECIFIED", "PREFER_NO_SCHEDULE", "NO_EXECUTE", ""}), + Description: `Specifies the nodes operating system (default: LINUX). Possible values: ["EFFECT_UNSPECIFIED", "PREFER_NO_SCHEDULE", "NO_EXECUTE"]`, + }, + "key": { + Type: schema.TypeString, + Optional: true, + Description: `Key associated with the effect.`, + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: `Value associated with the effect.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "api_server_args": { + Type: schema.TypeList, + Optional: true, + Description: `Customizes the default API server args. Only a subset of +customized flags are supported. Please refer to the API server +documentation below to know the exact format: +https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "argument": { + Type: schema.TypeString, + Required: true, + Description: `The argument name as it appears on the API Server command line please make sure to remove the leading dashes.`, + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: `The value of the arg as it will be passed to the API Server command line.`, + }, + }, + }, + }, + }, + }, + }, + "load_balancer": { + Type: schema.TypeList, + Required: true, + Description: `Specifies the load balancer configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "port_config": { + Type: schema.TypeList, + Required: true, + Description: `Specifies the load balancer ports.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "control_plane_load_balancer_port": { + Type: schema.TypeInt, + Required: true, + Description: `The port that control plane hosted load balancers will listen on.`, + }, + }, + }, + }, + "vip_config": { + Type: schema.TypeList, + Required: true, + Description: `Specified the Bare Metal Load Balancer Config`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "control_plane_vip": { + Type: schema.TypeString, + Required: true, + Description: `The VIP which you previously set aside for the Kubernetes API of this Bare Metal User Cluster.`, + }, + "ingress_vip": { + Type: schema.TypeString, + Required: true, + Description: `The VIP which you previously set aside for ingress traffic into this Bare Metal User Cluster.`, + }, + }, + }, + }, + "bgp_lb_config": { + Type: schema.TypeList, + Optional: true, + Description: `Configuration for BGP typed load balancers.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address_pools": { + Type: schema.TypeList, + Required: true, + Description: `AddressPools is a list of non-overlapping IP pools used by load balancer +typed services. All addresses must be routable to load balancer nodes. +IngressVIP must be included in the pools.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "addresses": { + Type: schema.TypeList, + Required: true, + Description: `The addresses that are part of this pool. Each address must be either in the CIDR form (1.2.3.0/24) or range form (1.2.3.1-1.2.3.5).`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "pool": { + Type: schema.TypeString, + Required: true, + Description: `The name of the address pool.`, + }, + "avoid_buggy_ips": { + Type: schema.TypeBool, + Optional: true, + Description: `If true, avoid using IPs ending in .0 or .255. +This avoids buggy consumer devices mistakenly dropping IPv4 traffic for those special IP addresses.`, + }, + "manual_assign": { + Type: schema.TypeString, + Optional: true, + Description: `If true, prevent IP addresses from being automatically assigned.`, + }, + }, + }, + }, + "asn": { + Type: schema.TypeInt, + Required: true, + Description: `BGP autonomous system number (ASN) of the cluster. +This field can be updated after cluster creation.`, + }, + "bgp_peer_configs": { + Type: schema.TypeList, + Required: true, + Description: `The list of BGP peers that the cluster will connect to. +At least one peer must be configured for each control plane node. +Control plane nodes will connect to these peers to advertise the control +plane VIP. The Services load balancer also uses these peers by default. +This field can be updated after cluster creation.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "asn": { + Type: schema.TypeInt, + Required: true, + Description: `BGP autonomous system number (ASN) for the network that contains the +external peer device.`, + }, + "ip_address": { + Type: schema.TypeString, + Required: true, + Description: `The IP address of the external peer device.`, + }, + "control_plane_nodes": { + Type: schema.TypeList, + Optional: true, + Description: `The IP address of the control plane node that connects to the external +peer. +If you don't specify any control plane nodes, all control plane nodes +can connect to the external peer. If you specify one or more IP addresses, +only the nodes specified participate in peering sessions.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "load_balancer_node_pool_config": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the node pool running data plane load balancing. L2 connectivity +is required among nodes in this pool. If missing, the control plane node +pool is used for data plane load balancing.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_pool_config": { + Type: schema.TypeList, + Optional: true, + Description: `The generic configuration for a node pool running a load balancer.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "kubelet_config": { + Type: schema.TypeList, + Optional: true, + Description: `The modifiable kubelet configurations for the baremetal machines.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "registry_burst": { + Type: schema.TypeInt, + Optional: true, + Description: `The maximum size of bursty pulls, temporarily allows pulls to burst to this +number, while still not exceeding registry_pull_qps. +The value must not be a negative number. +Updating this field may impact scalability by changing the amount of +traffic produced by image pulls. +Defaults to 10.`, + Default: 10, + }, + "registry_pull_qps": { + Type: schema.TypeInt, + Optional: true, + Description: `The limit of registry pulls per second. +Setting this value to 0 means no limit. +Updating this field may impact scalability by changing the amount of +traffic produced by image pulls. +Defaults to 5.`, + Default: 5, + }, + "serialize_image_pulls_disabled": { + Type: schema.TypeBool, + Optional: true, + Description: `Prevents the Kubelet from pulling multiple images at a time. +We recommend *not* changing the default value on nodes that run docker +daemon with version < 1.9 or an Another Union File System (Aufs) storage +backend. Issue https://github.com/kubernetes/kubernetes/issues/10959 has +more details.`, + }, + }, + }, + }, + "labels": { + Type: schema.TypeMap, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to +each node. These will added in addition to any default label(s) +that Kubernetes may apply to the node. In case of conflict in +label keys, the applied set may differ depending on the Kubernetes +version -- it's best to assume the behavior is undefined and +conflicts should be avoided. For more information, including usage +and the valid values, see: + http://kubernetes.io/v1.1/docs/user-guide/labels.html +An object containing a list of "key": value pairs. +Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "node_configs": { + Type: schema.TypeList, + Optional: true, + Description: `The list of machine addresses in the Bare Metal Node Pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "labels": { + Type: schema.TypeMap, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to +each node. These will added in addition to any default label(s) +that Kubernetes may apply to the node. In case of conflict in +label keys, the applied set may differ depending on the Kubernetes +version -- it's best to assume the behavior is undefined and +conflicts should be avoided. For more information, including usage +and the valid values, see: + http://kubernetes.io/v1.1/docs/user-guide/labels.html +An object containing a list of "key": value pairs. +Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "node_ip": { + Type: schema.TypeString, + Optional: true, + Description: `The default IPv4 address for SSH access and Kubernetes node. +Example: 192.168.0.1`, + }, + }, + }, + }, + "operating_system": { + Type: schema.TypeString, + Optional: true, + Description: `Specifies the nodes operating system (default: LINUX).`, + }, + "taints": { + Type: schema.TypeList, + Optional: true, + Description: `The initial taints assigned to nodes of this node pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "effect": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.ValidateEnum([]string{"EFFECT_UNSPECIFIED", "PREFER_NO_SCHEDULE", "NO_EXECUTE", ""}), + Description: `Specifies the nodes operating system (default: LINUX). Possible values: ["EFFECT_UNSPECIFIED", "PREFER_NO_SCHEDULE", "NO_EXECUTE"]`, + }, + "key": { + Type: schema.TypeString, + Optional: true, + Description: `Key associated with the effect.`, + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: `Value associated with the effect.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + ExactlyOneOf: []string{"load_balancer.0.metal_lb_config", "load_balancer.0.manual_lb_config", "load_balancer.0.bgp_lb_config"}, + }, + "manual_lb_config": { + Type: schema.TypeList, + Optional: true, + Description: `A nested object resource`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + Description: `Whether manual load balancing is enabled.`, + }, + }, + }, + ExactlyOneOf: []string{"load_balancer.0.metal_lb_config", "load_balancer.0.manual_lb_config", "load_balancer.0.bgp_lb_config"}, + }, + "metal_lb_config": { + Type: schema.TypeList, + Optional: true, + Description: `A nested object resource`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address_pools": { + Type: schema.TypeList, + Required: true, + Description: `AddressPools is a list of non-overlapping IP pools used by load balancer +typed services. All addresses must be routable to load balancer nodes. +IngressVIP must be included in the pools.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "addresses": { + Type: schema.TypeList, + Required: true, + Description: `The addresses that are part of this pool. Each address must be either in the CIDR form (1.2.3.0/24) or range form (1.2.3.1-1.2.3.5).`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "pool": { + Type: schema.TypeString, + Required: true, + Description: `The name of the address pool.`, + }, + "avoid_buggy_ips": { + Type: schema.TypeBool, + Optional: true, + Description: `If true, avoid using IPs ending in .0 or .255. +This avoids buggy consumer devices mistakenly dropping IPv4 traffic for those special IP addresses.`, + }, + "manual_assign": { + Type: schema.TypeBool, + Optional: true, + Description: `If true, prevent IP addresses from being automatically assigned.`, + }, + }, + }, + }, + "load_balancer_node_pool_config": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the load balancer's node pool configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_pool_config": { + Type: schema.TypeList, + Optional: true, + Description: `The generic configuration for a node pool running a load balancer.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "labels": { + Type: schema.TypeMap, + Computed: true, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to +each node. These will added in addition to any default label(s) +that Kubernetes may apply to the node. In case of conflict in +label keys, the applied set may differ depending on the Kubernetes +version -- it's best to assume the behavior is undefined and +conflicts should be avoided. For more information, including usage +and the valid values, see: + http://kubernetes.io/v1.1/docs/user-guide/labels.html +An object containing a list of "key": value pairs. +Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "node_configs": { + Type: schema.TypeList, + Optional: true, + Description: `The list of machine addresses in the Bare Metal Node Pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "labels": { + Type: schema.TypeMap, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to +each node. These will added in addition to any default label(s) +that Kubernetes may apply to the node. In case of conflict in +label keys, the applied set may differ depending on the Kubernetes +version -- it's best to assume the behavior is undefined and +conflicts should be avoided. For more information, including usage +and the valid values, see: + http://kubernetes.io/v1.1/docs/user-guide/labels.html +An object containing a list of "key": value pairs. +Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "node_ip": { + Type: schema.TypeString, + Optional: true, + Description: `The default IPv4 address for SSH access and Kubernetes node. +Example: 192.168.0.1`, + }, + }, + }, + }, + "operating_system": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: `Specifies the nodes operating system (default: LINUX).`, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: `The initial taints assigned to nodes of this node pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "effect": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.ValidateEnum([]string{"EFFECT_UNSPECIFIED", "PREFER_NO_SCHEDULE", "NO_EXECUTE", ""}), + Description: `Specifies the nodes operating system (default: LINUX). Possible values: ["EFFECT_UNSPECIFIED", "PREFER_NO_SCHEDULE", "NO_EXECUTE"]`, + }, + "key": { + Type: schema.TypeString, + Optional: true, + Description: `Key associated with the effect.`, + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: `Value associated with the effect.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + ExactlyOneOf: []string{"load_balancer.0.metal_lb_config", "load_balancer.0.manual_lb_config", "load_balancer.0.bgp_lb_config"}, + }, + }, + }, + }, + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The location of the resource.`, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The bare metal cluster name.`, + }, + "network_config": { + Type: schema.TypeList, + Required: true, + Description: `Network configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "advanced_networking": { + Type: schema.TypeBool, + Optional: true, + Description: `Enables the use of advanced Anthos networking features, such as Bundled +Load Balancing with BGP or the egress NAT gateway. +Setting configuration for advanced networking features will automatically +set this flag.`, + }, + "island_mode_cidr": { + Type: schema.TypeList, + Optional: true, + Description: `A nested object resource`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pod_address_cidr_blocks": { + Type: schema.TypeList, + Required: true, + Description: `All pods in the cluster are assigned an RFC1918 IPv4 address from these ranges. This field cannot be changed after creation.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "service_address_cidr_blocks": { + Type: schema.TypeList, + Required: true, + Description: `All services in the cluster are assigned an RFC1918 IPv4 address from these ranges. This field cannot be changed after creation.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + ExactlyOneOf: []string{"network_config.0.island_mode_cidr"}, + }, + "multiple_network_interfaces_config": { + Type: schema.TypeList, + Optional: true, + Description: `Configuration for multiple network interfaces.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: `Whether to enable multiple network interfaces for your pods. +When set network_config.advanced_networking is automatically +set to true.`, + }, + }, + }, + }, + "sr_iov_config": { + Type: schema.TypeList, + Optional: true, + Description: `Configuration for SR-IOV.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: `Whether to install the SR-IOV operator.`, + }, + }, + }, + }, + }, + }, + }, + "storage": { + Type: schema.TypeList, + Required: true, + Description: `Specifies the cluster storage configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "lvp_node_mounts_config": { + Type: schema.TypeList, + Required: true, + Description: `Specifies the config for local PersistentVolumes backed +by mounted node disks. These disks need to be formatted and mounted by the +user, which can be done before or after cluster creation.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "path": { + Type: schema.TypeString, + Required: true, + Description: `The host machine path.`, + }, + "storage_class": { + Type: schema.TypeString, + Required: true, + Description: `The StorageClass name that PVs will be created with.`, + }, + }, + }, + }, + "lvp_share_config": { + Type: schema.TypeList, + Required: true, + Description: `Specifies the config for local PersistentVolumes backed by +subdirectories in a shared filesystem. These subdirectores are +automatically created during cluster creation.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "lvp_config": { + Type: schema.TypeList, + Required: true, + Description: `Defines the machine path and storage class for the LVP Share.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "path": { + Type: schema.TypeString, + Required: true, + Description: `The host machine path.`, + }, + "storage_class": { + Type: schema.TypeString, + Required: true, + Description: `The StorageClass name that PVs will be created with.`, + }, + }, + }, + }, + "shared_path_pv_count": { + Type: schema.TypeInt, + Optional: true, + Description: `The number of subdirectories to create under path.`, + }, + }, + }, + }, + }, + }, + }, + "annotations": { + Type: schema.TypeMap, + Optional: true, + Description: `Annotations on the Bare Metal User Cluster. +This field has the same restrictions as Kubernetes annotations. +The total size of all keys and values combined is limited to 256k. +Key can have 2 segments: prefix (optional) and name (required), +separated by a slash (/). +Prefix must be a DNS subdomain. +Name must be 63 characters or less, begin and end with alphanumerics, +with dashes (-), underscores (_), dots (.), and alphanumerics between. + + +**Note**: This field is non-authoritative, and will only manage the annotations present in your configuration. +Please refer to the field 'effective_annotations' for all of the annotations present on the resource.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "binary_authorization": { + Type: schema.TypeList, + Optional: true, + Description: `Binary Authorization related configurations.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "evaluation_mode": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.ValidateEnum([]string{"DISABLED", "PROJECT_SINGLETON_POLICY_ENFORCE", ""}), + Description: `Mode of operation for binauthz policy evaluation. If unspecified, +defaults to DISABLED. Possible values: ["DISABLED", "PROJECT_SINGLETON_POLICY_ENFORCE"]`, + }, + }, + }, + }, + "cluster_operations": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the User Cluster's observability infrastructure.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enable_application_logs": { + Type: schema.TypeBool, + Optional: true, + Description: `Whether collection of application logs/metrics should be enabled (in addition to system logs/metrics).`, + }, + }, + }, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: `A human readable description of this Bare Metal User Cluster.`, + }, + "maintenance_config": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the workload node configurations.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "maintenance_address_cidr_blocks": { + Type: schema.TypeList, + Required: true, + Description: `All IPv4 address from these ranges will be placed into maintenance mode. +Nodes in maintenance mode will be cordoned and drained. When both of these +are true, the "baremetal.cluster.gke.io/maintenance" annotation will be set +on the node resource.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "node_access_config": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the node access related settings for the bare metal user cluster.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "login_user": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: `LoginUser is the user name used to access node machines. +It defaults to "root" if not set.`, + }, + }, + }, + }, + "node_config": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the workload node configurations.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "container_runtime": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ValidateFunc: verify.ValidateEnum([]string{"CONTAINER_RUNTIME_UNSPECIFIED", "DOCKER", "CONTAINERD", ""}), + Description: `The available runtimes that can be used to run containers in a Bare Metal User Cluster. Possible values: ["CONTAINER_RUNTIME_UNSPECIFIED", "DOCKER", "CONTAINERD"]`, + }, + "max_pods_per_node": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: `The maximum number of pods a node can run. The size of the CIDR range +assigned to the node will be derived from this parameter.`, + }, + }, + }, + }, + "os_environment_config": { + Type: schema.TypeList, + Optional: true, + Description: `OS environment related configurations.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "package_repo_excluded": { + Type: schema.TypeBool, + Required: true, + Description: `Whether the package repo should not be included when initializing +bare metal machines.`, + }, + }, + }, + }, + "proxy": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the cluster proxy configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uri": { + Type: schema.TypeString, + Required: true, + Description: `Specifies the address of your proxy server. +Examples: http://domain +WARNING: Do not provide credentials in the format +http://(username:password@)domain these will be rejected by the server.`, + }, + "no_proxy": { + Type: schema.TypeList, + Optional: true, + Description: `A list of IPs, hostnames, and domains that should skip the proxy. +Examples: ["127.0.0.1", "example.com", ".corp", "localhost"].`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "security_config": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies the security related settings for the Bare Metal User Cluster.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorization": { + Type: schema.TypeList, + Optional: true, + Description: `Configures user access to the Bare Metal User cluster.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "admin_users": { + Type: schema.TypeList, + Required: true, + Description: `Users that will be granted the cluster-admin role on the cluster, providing full access to the cluster.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + Description: `The name of the user, e.g. 'my-gcp-id@gmail.com'.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "upgrade_policy": { + Type: schema.TypeList, + Optional: true, + Description: `The cluster upgrade policy.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "policy": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.ValidateEnum([]string{"SERIAL", "CONCURRENT", ""}), + Description: `Specifies which upgrade policy to use. Possible values: ["SERIAL", "CONCURRENT"]`, + }, + }, + }, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was created, in RFC3339 text format.`, + }, + "delete_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was deleted, in RFC3339 text format.`, + }, + "effective_annotations": { + Type: schema.TypeMap, + Computed: true, + Description: `All of annotations (key/value pairs) present on the resource in GCP, including the annotations configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "endpoint": { + Type: schema.TypeString, + Computed: true, + Description: `The IP address name of Bare Metal User Cluster's API server.`, + }, + "etag": { + Type: schema.TypeString, + Computed: true, + Description: `This checksum is computed by the server based on the value of other +fields, and may be sent on update and delete requests to ensure the +client has an up-to-date value before proceeding. +Allows clients to perform consistent read-modify-writes +through optimistic concurrency control.`, + }, + "fleet": { + Type: schema.TypeList, + Computed: true, + Description: `Fleet related configuration. +Fleets are a Google Cloud concept for logically organizing clusters, +letting you use and manage multi-cluster capabilities and apply +consistent policies across your systems. +See [Anthos Fleets](https://cloud.google.com/anthos/multicluster-management/fleets) for +more details on Anthos multi-cluster capabilities using Fleets.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "membership": { + Type: schema.TypeString, + Computed: true, + Description: `The name of the managed Hub Membership resource associated to this cluster. +Membership names are formatted as +'projects//locations//memberships/'.`, + }, + }, + }, + }, + "local_name": { + Type: schema.TypeString, + Computed: true, + Description: `The object name of the Bare Metal Cluster custom resource on the +associated admin cluster. This field is used to support conflicting +names when enrolling existing clusters to the API. When used as a part of +cluster enrollment, this field will differ from the ID in the resource +name. For new clusters, this field will match the user provided cluster ID +and be visible in the last component of the resource name. It is not +modifiable. +All users should use this name to access their cluster using gkectl or +kubectl and should expect to see the local name when viewing admin +cluster controller logs.`, + }, + "reconciling": { + Type: schema.TypeBool, + Computed: true, + Description: `If set, there are currently changes in flight to the Bare Metal User Cluster.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The current state of this cluster.`, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Description: `Specifies detailed cluster status.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "conditions": { + Type: schema.TypeList, + Computed: true, + Description: `ResourceConditions provide a standard mechanism for higher-level status reporting from user cluster controller.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "message": { + Type: schema.TypeString, + Optional: true, + Description: `Human-readable message indicating details about last transition.`, + }, + "reason": { + Type: schema.TypeString, + Optional: true, + Description: `Machine-readable message indicating details about last transition.`, + }, + "type": { + Type: schema.TypeString, + Optional: true, + Description: `Type of the condition. +(e.g., ClusterRunning, NodePoolRunning or ServerSidePreflightReady)`, + }, + "last_transition_time": { + Type: schema.TypeString, + Computed: true, + Description: `Last time the condition transit from one status to another.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The lifecycle state of the condition.`, + }, + }, + }, + }, + "error_message": { + Type: schema.TypeString, + Computed: true, + Description: `Human-friendly representation of the error message from the user cluster +controller. The error message can be temporary as the user cluster +controller creates a cluster or node pool. If the error message persists +for a longer period of time, it can be used to surface error message to +indicate real problems requiring user intervention.`, + }, + }, + }, + }, + "uid": { + Type: schema.TypeString, + Computed: true, + Description: `The unique identifier of the Bare Metal User Cluster.`, + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was last updated, in RFC3339 text format.`, + }, + "validation_check": { + Type: schema.TypeList, + Computed: true, + Description: `Specifies the security related settings for the Bare Metal User Cluster.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "options": { + Type: schema.TypeString, + Computed: true, + Description: `Options used for the validation check.`, + }, + "scenario": { + Type: schema.TypeString, + Computed: true, + Description: `The scenario when the preflight checks were run..`, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Description: `Specifies the detailed validation check status`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "result": { + Type: schema.TypeList, + Computed: true, + Description: `Individual checks which failed as part of the Preflight check execution.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "category": { + Type: schema.TypeString, + Computed: true, + Description: `The category of the validation.`, + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: `The description of the validation check.`, + }, + "details": { + Type: schema.TypeString, + Computed: true, + Description: `Detailed failure information, which might be unformatted.`, + }, + "options": { + Type: schema.TypeString, + Computed: true, + Description: `Options used for the validation check.`, + }, + "reason": { + Type: schema.TypeString, + Computed: true, + Description: `A human-readable message of the check failure.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + UseJSONNumber: true, + } +} + +func resourceGkeonpremBareMetalClusterCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + adminClusterMembershipProp, err := expandGkeonpremBareMetalClusterAdminClusterMembership(d.Get("admin_cluster_membership"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("admin_cluster_membership"); !tpgresource.IsEmptyValue(reflect.ValueOf(adminClusterMembershipProp)) && (ok || !reflect.DeepEqual(v, adminClusterMembershipProp)) { + obj["adminClusterMembership"] = adminClusterMembershipProp + } + descriptionProp, err := expandGkeonpremBareMetalClusterDescription(d.Get("description"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + bareMetalVersionProp, err := expandGkeonpremBareMetalClusterBareMetalVersion(d.Get("bare_metal_version"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("bare_metal_version"); !tpgresource.IsEmptyValue(reflect.ValueOf(bareMetalVersionProp)) && (ok || !reflect.DeepEqual(v, bareMetalVersionProp)) { + obj["bareMetalVersion"] = bareMetalVersionProp + } + networkConfigProp, err := expandGkeonpremBareMetalClusterNetworkConfig(d.Get("network_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("network_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(networkConfigProp)) && (ok || !reflect.DeepEqual(v, networkConfigProp)) { + obj["networkConfig"] = networkConfigProp + } + controlPlaneProp, err := expandGkeonpremBareMetalClusterControlPlane(d.Get("control_plane"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("control_plane"); !tpgresource.IsEmptyValue(reflect.ValueOf(controlPlaneProp)) && (ok || !reflect.DeepEqual(v, controlPlaneProp)) { + obj["controlPlane"] = controlPlaneProp + } + loadBalancerProp, err := expandGkeonpremBareMetalClusterLoadBalancer(d.Get("load_balancer"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("load_balancer"); !tpgresource.IsEmptyValue(reflect.ValueOf(loadBalancerProp)) && (ok || !reflect.DeepEqual(v, loadBalancerProp)) { + obj["loadBalancer"] = loadBalancerProp + } + storageProp, err := expandGkeonpremBareMetalClusterStorage(d.Get("storage"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("storage"); !tpgresource.IsEmptyValue(reflect.ValueOf(storageProp)) && (ok || !reflect.DeepEqual(v, storageProp)) { + obj["storage"] = storageProp + } + proxyProp, err := expandGkeonpremBareMetalClusterProxy(d.Get("proxy"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("proxy"); !tpgresource.IsEmptyValue(reflect.ValueOf(proxyProp)) && (ok || !reflect.DeepEqual(v, proxyProp)) { + obj["proxy"] = proxyProp + } + clusterOperationsProp, err := expandGkeonpremBareMetalClusterClusterOperations(d.Get("cluster_operations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("cluster_operations"); !tpgresource.IsEmptyValue(reflect.ValueOf(clusterOperationsProp)) && (ok || !reflect.DeepEqual(v, clusterOperationsProp)) { + obj["clusterOperations"] = clusterOperationsProp + } + maintenanceConfigProp, err := expandGkeonpremBareMetalClusterMaintenanceConfig(d.Get("maintenance_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("maintenance_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(maintenanceConfigProp)) && (ok || !reflect.DeepEqual(v, maintenanceConfigProp)) { + obj["maintenanceConfig"] = maintenanceConfigProp + } + nodeConfigProp, err := expandGkeonpremBareMetalClusterNodeConfig(d.Get("node_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(nodeConfigProp)) && (ok || !reflect.DeepEqual(v, nodeConfigProp)) { + obj["nodeConfig"] = nodeConfigProp + } + nodeAccessConfigProp, err := expandGkeonpremBareMetalClusterNodeAccessConfig(d.Get("node_access_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_access_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(nodeAccessConfigProp)) && (ok || !reflect.DeepEqual(v, nodeAccessConfigProp)) { + obj["nodeAccessConfig"] = nodeAccessConfigProp + } + osEnvironmentConfigProp, err := expandGkeonpremBareMetalClusterOsEnvironmentConfig(d.Get("os_environment_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("os_environment_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(osEnvironmentConfigProp)) && (ok || !reflect.DeepEqual(v, osEnvironmentConfigProp)) { + obj["osEnvironmentConfig"] = osEnvironmentConfigProp + } + securityConfigProp, err := expandGkeonpremBareMetalClusterSecurityConfig(d.Get("security_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("security_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(securityConfigProp)) && (ok || !reflect.DeepEqual(v, securityConfigProp)) { + obj["securityConfig"] = securityConfigProp + } + binaryAuthorizationProp, err := expandGkeonpremBareMetalClusterBinaryAuthorization(d.Get("binary_authorization"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("binary_authorization"); !tpgresource.IsEmptyValue(reflect.ValueOf(binaryAuthorizationProp)) && (ok || !reflect.DeepEqual(v, binaryAuthorizationProp)) { + obj["binaryAuthorization"] = binaryAuthorizationProp + } + upgradePolicyProp, err := expandGkeonpremBareMetalClusterUpgradePolicy(d.Get("upgrade_policy"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("upgrade_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(upgradePolicyProp)) && (ok || !reflect.DeepEqual(v, upgradePolicyProp)) { + obj["upgradePolicy"] = upgradePolicyProp + } + annotationsProp, err := expandGkeonpremBareMetalClusterEffectiveAnnotations(d.Get("effective_annotations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_annotations"); !tpgresource.IsEmptyValue(reflect.ValueOf(annotationsProp)) && (ok || !reflect.DeepEqual(v, annotationsProp)) { + obj["annotations"] = annotationsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalClusters?bare_metal_cluster_id={{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new BareMetalCluster: %#v", obj) + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalCluster: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "POST", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutCreate), + }) + if err != nil { + return fmt.Errorf("Error creating BareMetalCluster: %s", err) + } + + // Store the ID now + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/bareMetalClusters/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + // Use the resource in the operation response to populate + // identity fields and d.Id() before read + var opRes map[string]interface{} + err = GkeonpremOperationWaitTimeWithResponse( + config, res, &opRes, project, "Creating BareMetalCluster", userAgent, + d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error waiting to create BareMetalCluster: %s", err) + } + + // This may have caused the ID to update - update it if so. + id, err = tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/bareMetalClusters/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating BareMetalCluster %q: %#v", d.Id(), res) + + return resourceGkeonpremBareMetalClusterRead(d, meta) +} + +func resourceGkeonpremBareMetalClusterRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalClusters/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalCluster: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("GkeonpremBareMetalCluster %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + + if err := d.Set("admin_cluster_membership", flattenGkeonpremBareMetalClusterAdminClusterMembership(res["adminClusterMembership"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("description", flattenGkeonpremBareMetalClusterDescription(res["description"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("bare_metal_version", flattenGkeonpremBareMetalClusterBareMetalVersion(res["bareMetalVersion"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("annotations", flattenGkeonpremBareMetalClusterAnnotations(res["annotations"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("network_config", flattenGkeonpremBareMetalClusterNetworkConfig(res["networkConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("control_plane", flattenGkeonpremBareMetalClusterControlPlane(res["controlPlane"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("load_balancer", flattenGkeonpremBareMetalClusterLoadBalancer(res["loadBalancer"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("storage", flattenGkeonpremBareMetalClusterStorage(res["storage"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("proxy", flattenGkeonpremBareMetalClusterProxy(res["proxy"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("cluster_operations", flattenGkeonpremBareMetalClusterClusterOperations(res["clusterOperations"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("maintenance_config", flattenGkeonpremBareMetalClusterMaintenanceConfig(res["maintenanceConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("node_config", flattenGkeonpremBareMetalClusterNodeConfig(res["nodeConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("node_access_config", flattenGkeonpremBareMetalClusterNodeAccessConfig(res["nodeAccessConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("os_environment_config", flattenGkeonpremBareMetalClusterOsEnvironmentConfig(res["osEnvironmentConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("security_config", flattenGkeonpremBareMetalClusterSecurityConfig(res["securityConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("binary_authorization", flattenGkeonpremBareMetalClusterBinaryAuthorization(res["binaryAuthorization"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("upgrade_policy", flattenGkeonpremBareMetalClusterUpgradePolicy(res["upgradePolicy"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("uid", flattenGkeonpremBareMetalClusterUid(res["uid"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("state", flattenGkeonpremBareMetalClusterState(res["state"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("endpoint", flattenGkeonpremBareMetalClusterEndpoint(res["endpoint"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("reconciling", flattenGkeonpremBareMetalClusterReconciling(res["reconciling"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("create_time", flattenGkeonpremBareMetalClusterCreateTime(res["createTime"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("update_time", flattenGkeonpremBareMetalClusterUpdateTime(res["updateTime"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("delete_time", flattenGkeonpremBareMetalClusterDeleteTime(res["deleteTime"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("local_name", flattenGkeonpremBareMetalClusterLocalName(res["localName"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("etag", flattenGkeonpremBareMetalClusterEtag(res["etag"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("fleet", flattenGkeonpremBareMetalClusterFleet(res["fleet"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("status", flattenGkeonpremBareMetalClusterStatus(res["status"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("validation_check", flattenGkeonpremBareMetalClusterValidationCheck(res["validationCheck"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + if err := d.Set("effective_annotations", flattenGkeonpremBareMetalClusterEffectiveAnnotations(res["annotations"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalCluster: %s", err) + } + + return nil +} + +func resourceGkeonpremBareMetalClusterUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalCluster: %s", err) + } + billingProject = project + + obj := make(map[string]interface{}) + descriptionProp, err := expandGkeonpremBareMetalClusterDescription(d.Get("description"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + bareMetalVersionProp, err := expandGkeonpremBareMetalClusterBareMetalVersion(d.Get("bare_metal_version"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("bare_metal_version"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, bareMetalVersionProp)) { + obj["bareMetalVersion"] = bareMetalVersionProp + } + networkConfigProp, err := expandGkeonpremBareMetalClusterNetworkConfig(d.Get("network_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("network_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, networkConfigProp)) { + obj["networkConfig"] = networkConfigProp + } + controlPlaneProp, err := expandGkeonpremBareMetalClusterControlPlane(d.Get("control_plane"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("control_plane"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, controlPlaneProp)) { + obj["controlPlane"] = controlPlaneProp + } + loadBalancerProp, err := expandGkeonpremBareMetalClusterLoadBalancer(d.Get("load_balancer"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("load_balancer"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, loadBalancerProp)) { + obj["loadBalancer"] = loadBalancerProp + } + storageProp, err := expandGkeonpremBareMetalClusterStorage(d.Get("storage"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("storage"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, storageProp)) { + obj["storage"] = storageProp + } + proxyProp, err := expandGkeonpremBareMetalClusterProxy(d.Get("proxy"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("proxy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, proxyProp)) { + obj["proxy"] = proxyProp + } + clusterOperationsProp, err := expandGkeonpremBareMetalClusterClusterOperations(d.Get("cluster_operations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("cluster_operations"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, clusterOperationsProp)) { + obj["clusterOperations"] = clusterOperationsProp + } + maintenanceConfigProp, err := expandGkeonpremBareMetalClusterMaintenanceConfig(d.Get("maintenance_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("maintenance_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, maintenanceConfigProp)) { + obj["maintenanceConfig"] = maintenanceConfigProp + } + nodeConfigProp, err := expandGkeonpremBareMetalClusterNodeConfig(d.Get("node_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nodeConfigProp)) { + obj["nodeConfig"] = nodeConfigProp + } + nodeAccessConfigProp, err := expandGkeonpremBareMetalClusterNodeAccessConfig(d.Get("node_access_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_access_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nodeAccessConfigProp)) { + obj["nodeAccessConfig"] = nodeAccessConfigProp + } + osEnvironmentConfigProp, err := expandGkeonpremBareMetalClusterOsEnvironmentConfig(d.Get("os_environment_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("os_environment_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, osEnvironmentConfigProp)) { + obj["osEnvironmentConfig"] = osEnvironmentConfigProp + } + securityConfigProp, err := expandGkeonpremBareMetalClusterSecurityConfig(d.Get("security_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("security_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, securityConfigProp)) { + obj["securityConfig"] = securityConfigProp + } + binaryAuthorizationProp, err := expandGkeonpremBareMetalClusterBinaryAuthorization(d.Get("binary_authorization"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("binary_authorization"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, binaryAuthorizationProp)) { + obj["binaryAuthorization"] = binaryAuthorizationProp + } + upgradePolicyProp, err := expandGkeonpremBareMetalClusterUpgradePolicy(d.Get("upgrade_policy"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("upgrade_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, upgradePolicyProp)) { + obj["upgradePolicy"] = upgradePolicyProp + } + annotationsProp, err := expandGkeonpremBareMetalClusterEffectiveAnnotations(d.Get("effective_annotations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_annotations"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, annotationsProp)) { + obj["annotations"] = annotationsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalClusters/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating BareMetalCluster %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("description") { + updateMask = append(updateMask, "description") + } + + if d.HasChange("bare_metal_version") { + updateMask = append(updateMask, "bareMetalVersion") + } + + if d.HasChange("network_config") { + updateMask = append(updateMask, "networkConfig") + } + + if d.HasChange("control_plane") { + updateMask = append(updateMask, "controlPlane") + } + + if d.HasChange("load_balancer") { + updateMask = append(updateMask, "loadBalancer") + } + + if d.HasChange("storage") { + updateMask = append(updateMask, "storage") + } + + if d.HasChange("proxy") { + updateMask = append(updateMask, "proxy") + } + + if d.HasChange("cluster_operations") { + updateMask = append(updateMask, "clusterOperations") + } + + if d.HasChange("maintenance_config") { + updateMask = append(updateMask, "maintenanceConfig") + } + + if d.HasChange("node_config") { + updateMask = append(updateMask, "nodeConfig") + } + + if d.HasChange("node_access_config") { + updateMask = append(updateMask, "nodeAccessConfig") + } + + if d.HasChange("os_environment_config") { + updateMask = append(updateMask, "osEnvironmentConfig") + } + + if d.HasChange("security_config") { + updateMask = append(updateMask, "securityConfig") + } + + if d.HasChange("binary_authorization") { + updateMask = append(updateMask, "binaryAuthorization") + } + + if d.HasChange("upgrade_policy") { + updateMask = append(updateMask, "upgradePolicy") + } + + if d.HasChange("effective_annotations") { + updateMask = append(updateMask, "annotations") + } + // updateMask is a URL parameter but not present in the schema, so ReplaceVars + // won't set it + url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + // if updateMask is empty we are not updating anything so skip the post + if len(updateMask) > 0 { + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "PATCH", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutUpdate), + }) + + if err != nil { + return fmt.Errorf("Error updating BareMetalCluster %q: %s", d.Id(), err) + } else { + log.Printf("[DEBUG] Finished updating BareMetalCluster %q: %#v", d.Id(), res) + } + + err = GkeonpremOperationWaitTime( + config, res, project, "Updating BareMetalCluster", userAgent, + d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return err + } + } + + return resourceGkeonpremBareMetalClusterRead(d, meta) +} + +func resourceGkeonpremBareMetalClusterDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalCluster: %s", err) + } + billingProject = project + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalClusters/{{name}}?force=true") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting BareMetalCluster %q", d.Id()) + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutDelete), + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, "BareMetalCluster") + } + + err = GkeonpremOperationWaitTime( + config, res, project, "Deleting BareMetalCluster", userAgent, + d.Timeout(schema.TimeoutDelete)) + + if err != nil { + return err + } + + log.Printf("[DEBUG] Finished deleting BareMetalCluster %q: %#v", d.Id(), res) + return nil +} + +func resourceGkeonpremBareMetalClusterImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*transport_tpg.Config) + if err := tpgresource.ParseImportId([]string{ + "^projects/(?P[^/]+)/locations/(?P[^/]+)/bareMetalClusters/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)$", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/bareMetalClusters/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenGkeonpremBareMetalClusterAdminClusterMembership(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterBareMetalVersion(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("annotations"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenGkeonpremBareMetalClusterNetworkConfig(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["island_mode_cidr"] = + flattenGkeonpremBareMetalClusterNetworkConfigIslandModeCidr(original["islandModeCidr"], d, config) + transformed["advanced_networking"] = + flattenGkeonpremBareMetalClusterNetworkConfigAdvancedNetworking(original["advancedNetworking"], d, config) + transformed["multiple_network_interfaces_config"] = + flattenGkeonpremBareMetalClusterNetworkConfigMultipleNetworkInterfacesConfig(original["multipleNetworkInterfacesConfig"], d, config) + transformed["sr_iov_config"] = + flattenGkeonpremBareMetalClusterNetworkConfigSrIovConfig(original["srIovConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterNetworkConfigIslandModeCidr(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["service_address_cidr_blocks"] = + flattenGkeonpremBareMetalClusterNetworkConfigIslandModeCidrServiceAddressCidrBlocks(original["serviceAddressCidrBlocks"], d, config) + transformed["pod_address_cidr_blocks"] = + flattenGkeonpremBareMetalClusterNetworkConfigIslandModeCidrPodAddressCidrBlocks(original["podAddressCidrBlocks"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterNetworkConfigIslandModeCidrServiceAddressCidrBlocks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterNetworkConfigIslandModeCidrPodAddressCidrBlocks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterNetworkConfigAdvancedNetworking(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterNetworkConfigMultipleNetworkInterfacesConfig(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["enabled"] = + flattenGkeonpremBareMetalClusterNetworkConfigMultipleNetworkInterfacesConfigEnabled(original["enabled"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterNetworkConfigMultipleNetworkInterfacesConfigEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterNetworkConfigSrIovConfig(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["enabled"] = + flattenGkeonpremBareMetalClusterNetworkConfigSrIovConfigEnabled(original["enabled"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterNetworkConfigSrIovConfigEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterControlPlane(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["control_plane_node_pool_config"] = + flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfig(original["controlPlaneNodePoolConfig"], d, config) + transformed["api_server_args"] = + flattenGkeonpremBareMetalClusterControlPlaneApiServerArgs(original["apiServerArgs"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfig(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["node_pool_config"] = + flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfig(original["nodePoolConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfig(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["node_configs"] = + flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigs(original["nodeConfigs"], d, config) + transformed["operating_system"] = + flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigOperatingSystem(original["operatingSystem"], d, config) + transformed["taints"] = + flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaints(original["taints"], d, config) + transformed["labels"] = + flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigLabels(original["labels"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigs(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{}{ + "node_ip": flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsNodeIp(original["nodeIp"], d, config), + "labels": flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsLabels(original["labels"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsNodeIp(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigOperatingSystem(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaints(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{}{ + "key": flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsKey(original["key"], d, config), + "value": flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsValue(original["value"], d, config), + "effect": flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsEffect(original["effect"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsValue(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsEffect(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterControlPlaneApiServerArgs(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{}{ + "argument": flattenGkeonpremBareMetalClusterControlPlaneApiServerArgsArgument(original["argument"], d, config), + "value": flattenGkeonpremBareMetalClusterControlPlaneApiServerArgsValue(original["value"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterControlPlaneApiServerArgsArgument(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterControlPlaneApiServerArgsValue(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancer(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["vip_config"] = + flattenGkeonpremBareMetalClusterLoadBalancerVipConfig(original["vipConfig"], d, config) + transformed["port_config"] = + flattenGkeonpremBareMetalClusterLoadBalancerPortConfig(original["portConfig"], d, config) + transformed["metal_lb_config"] = + flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfig(original["metalLbConfig"], d, config) + transformed["manual_lb_config"] = + flattenGkeonpremBareMetalClusterLoadBalancerManualLbConfig(original["manualLbConfig"], d, config) + transformed["bgp_lb_config"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfig(original["bgpLbConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerVipConfig(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["control_plane_vip"] = + flattenGkeonpremBareMetalClusterLoadBalancerVipConfigControlPlaneVip(original["controlPlaneVip"], d, config) + transformed["ingress_vip"] = + flattenGkeonpremBareMetalClusterLoadBalancerVipConfigIngressVip(original["ingressVip"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerVipConfigControlPlaneVip(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerVipConfigIngressVip(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerPortConfig(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["control_plane_load_balancer_port"] = + flattenGkeonpremBareMetalClusterLoadBalancerPortConfigControlPlaneLoadBalancerPort(original["controlPlaneLoadBalancerPort"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerPortConfigControlPlaneLoadBalancerPort(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 flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfig(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["address_pools"] = + flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPools(original["addressPools"], d, config) + transformed["load_balancer_node_pool_config"] = + flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfig(original["loadBalancerNodePoolConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPools(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{}{ + "pool": flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsPool(original["pool"], d, config), + "addresses": flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsAddresses(original["addresses"], d, config), + "avoid_buggy_ips": flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsAvoidBuggyIps(original["avoidBuggyIps"], d, config), + "manual_assign": flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsManualAssign(original["manualAssign"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsPool(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsAddresses(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsAvoidBuggyIps(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsManualAssign(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfig(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["node_pool_config"] = + flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfig(original["nodePoolConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfig(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["node_configs"] = + flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigs(original["nodeConfigs"], d, config) + transformed["operating_system"] = + flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigOperatingSystem(original["operatingSystem"], d, config) + transformed["taints"] = + flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaints(original["taints"], d, config) + transformed["labels"] = + flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigLabels(original["labels"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigs(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{}{ + "node_ip": flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsNodeIp(original["nodeIp"], d, config), + "labels": flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsLabels(original["labels"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsNodeIp(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigOperatingSystem(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaints(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{}{ + "key": flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsKey(original["key"], d, config), + "value": flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsValue(original["value"], d, config), + "effect": flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsEffect(original["effect"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsValue(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsEffect(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerManualLbConfig(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["enabled"] = + flattenGkeonpremBareMetalClusterLoadBalancerManualLbConfigEnabled(original["enabled"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerManualLbConfigEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfig(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["asn"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAsn(original["asn"], d, config) + transformed["bgp_peer_configs"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigs(original["bgpPeerConfigs"], d, config) + transformed["address_pools"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPools(original["addressPools"], d, config) + transformed["load_balancer_node_pool_config"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfig(original["loadBalancerNodePoolConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAsn(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 flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigs(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{}{ + "asn": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsAsn(original["asn"], d, config), + "ip_address": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsIpAddress(original["ipAddress"], d, config), + "control_plane_nodes": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsControlPlaneNodes(original["controlPlaneNodes"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsAsn(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 flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsIpAddress(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsControlPlaneNodes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPools(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{}{ + "pool": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsPool(original["pool"], d, config), + "addresses": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsAddresses(original["addresses"], d, config), + "avoid_buggy_ips": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsAvoidBuggyIps(original["avoidBuggyIps"], d, config), + "manual_assign": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsManualAssign(original["manualAssign"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsPool(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsAddresses(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsAvoidBuggyIps(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsManualAssign(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfig(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["node_pool_config"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfig(original["nodePoolConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfig(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["node_configs"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigs(original["nodeConfigs"], d, config) + transformed["operating_system"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigOperatingSystem(original["operatingSystem"], d, config) + transformed["taints"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaints(original["taints"], d, config) + transformed["labels"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigLabels(original["labels"], d, config) + transformed["kubelet_config"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfig(original["kubeletConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigs(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{}{ + "node_ip": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsNodeIp(original["nodeIp"], d, config), + "labels": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsLabels(original["labels"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsNodeIp(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigOperatingSystem(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaints(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{}{ + "key": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsKey(original["key"], d, config), + "value": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsValue(original["value"], d, config), + "effect": flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsEffect(original["effect"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsValue(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsEffect(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfig(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["registry_pull_qps"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigRegistryPullQps(original["registryPullQps"], d, config) + transformed["registry_burst"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigRegistryBurst(original["registryBurst"], d, config) + transformed["serialize_image_pulls_disabled"] = + flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigSerializeImagePullsDisabled(original["serializeImagePullsDisabled"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigRegistryPullQps(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 flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigRegistryBurst(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 flattenGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigSerializeImagePullsDisabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterStorage(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["lvp_share_config"] = + flattenGkeonpremBareMetalClusterStorageLvpShareConfig(original["lvpShareConfig"], d, config) + transformed["lvp_node_mounts_config"] = + flattenGkeonpremBareMetalClusterStorageLvpNodeMountsConfig(original["lvpNodeMountsConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterStorageLvpShareConfig(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["lvp_config"] = + flattenGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfig(original["lvpConfig"], d, config) + transformed["shared_path_pv_count"] = + flattenGkeonpremBareMetalClusterStorageLvpShareConfigSharedPathPvCount(original["sharedPathPvCount"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfig(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["path"] = + flattenGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfigPath(original["path"], d, config) + transformed["storage_class"] = + flattenGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfigStorageClass(original["storageClass"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfigPath(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfigStorageClass(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterStorageLvpShareConfigSharedPathPvCount(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 flattenGkeonpremBareMetalClusterStorageLvpNodeMountsConfig(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["path"] = + flattenGkeonpremBareMetalClusterStorageLvpNodeMountsConfigPath(original["path"], d, config) + transformed["storage_class"] = + flattenGkeonpremBareMetalClusterStorageLvpNodeMountsConfigStorageClass(original["storageClass"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterStorageLvpNodeMountsConfigPath(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterStorageLvpNodeMountsConfigStorageClass(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterProxy(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["uri"] = + flattenGkeonpremBareMetalClusterProxyUri(original["uri"], d, config) + transformed["no_proxy"] = + flattenGkeonpremBareMetalClusterProxyNoProxy(original["noProxy"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterProxyUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterProxyNoProxy(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterClusterOperations(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["enable_application_logs"] = + flattenGkeonpremBareMetalClusterClusterOperationsEnableApplicationLogs(original["enableApplicationLogs"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterClusterOperationsEnableApplicationLogs(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterMaintenanceConfig(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["maintenance_address_cidr_blocks"] = + flattenGkeonpremBareMetalClusterMaintenanceConfigMaintenanceAddressCidrBlocks(original["maintenanceAddressCidrBlocks"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterMaintenanceConfigMaintenanceAddressCidrBlocks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterNodeConfig(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_pods_per_node"] = + flattenGkeonpremBareMetalClusterNodeConfigMaxPodsPerNode(original["maxPodsPerNode"], d, config) + transformed["container_runtime"] = + flattenGkeonpremBareMetalClusterNodeConfigContainerRuntime(original["containerRuntime"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterNodeConfigMaxPodsPerNode(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 flattenGkeonpremBareMetalClusterNodeConfigContainerRuntime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterNodeAccessConfig(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["login_user"] = + flattenGkeonpremBareMetalClusterNodeAccessConfigLoginUser(original["loginUser"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterNodeAccessConfigLoginUser(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterOsEnvironmentConfig(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["package_repo_excluded"] = + flattenGkeonpremBareMetalClusterOsEnvironmentConfigPackageRepoExcluded(original["packageRepoExcluded"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterOsEnvironmentConfigPackageRepoExcluded(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterSecurityConfig(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["authorization"] = + flattenGkeonpremBareMetalClusterSecurityConfigAuthorization(original["authorization"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterSecurityConfigAuthorization(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["admin_users"] = + flattenGkeonpremBareMetalClusterSecurityConfigAuthorizationAdminUsers(original["adminUsers"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterSecurityConfigAuthorizationAdminUsers(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{}{ + "username": flattenGkeonpremBareMetalClusterSecurityConfigAuthorizationAdminUsersUsername(original["username"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterSecurityConfigAuthorizationAdminUsersUsername(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterBinaryAuthorization(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["evaluation_mode"] = + flattenGkeonpremBareMetalClusterBinaryAuthorizationEvaluationMode(original["evaluationMode"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterBinaryAuthorizationEvaluationMode(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterUpgradePolicy(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["policy"] = + flattenGkeonpremBareMetalClusterUpgradePolicyPolicy(original["policy"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterUpgradePolicyPolicy(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterUid(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterEndpoint(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterReconciling(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterUpdateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterDeleteTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterLocalName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterEtag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterFleet(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["membership"] = + flattenGkeonpremBareMetalClusterFleetMembership(original["membership"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterFleetMembership(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterStatus(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["error_message"] = + flattenGkeonpremBareMetalClusterStatusErrorMessage(original["errorMessage"], d, config) + transformed["conditions"] = + flattenGkeonpremBareMetalClusterStatusConditions(original["conditions"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterStatusErrorMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterStatusConditions(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{}{ + "type": flattenGkeonpremBareMetalClusterStatusConditionsType(original["type"], d, config), + "reason": flattenGkeonpremBareMetalClusterStatusConditionsReason(original["reason"], d, config), + "message": flattenGkeonpremBareMetalClusterStatusConditionsMessage(original["message"], d, config), + "last_transition_time": flattenGkeonpremBareMetalClusterStatusConditionsLastTransitionTime(original["lastTransitionTime"], d, config), + "state": flattenGkeonpremBareMetalClusterStatusConditionsState(original["state"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterStatusConditionsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterStatusConditionsReason(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterStatusConditionsMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterStatusConditionsLastTransitionTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterStatusConditionsState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterValidationCheck(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["options"] = + flattenGkeonpremBareMetalClusterValidationCheckOptions(original["options"], d, config) + transformed["status"] = + flattenGkeonpremBareMetalClusterValidationCheckStatus(original["status"], d, config) + transformed["scenario"] = + flattenGkeonpremBareMetalClusterValidationCheckScenario(original["scenario"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterValidationCheckOptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterValidationCheckStatus(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["result"] = + flattenGkeonpremBareMetalClusterValidationCheckStatusResult(original["result"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalClusterValidationCheckStatusResult(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{}{ + "options": flattenGkeonpremBareMetalClusterValidationCheckStatusResultOptions(original["options"], d, config), + "description": flattenGkeonpremBareMetalClusterValidationCheckStatusResultDescription(original["description"], d, config), + "category": flattenGkeonpremBareMetalClusterValidationCheckStatusResultCategory(original["category"], d, config), + "reason": flattenGkeonpremBareMetalClusterValidationCheckStatusResultReason(original["reason"], d, config), + "details": flattenGkeonpremBareMetalClusterValidationCheckStatusResultDetails(original["details"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalClusterValidationCheckStatusResultOptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterValidationCheckStatusResultDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterValidationCheckStatusResultCategory(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterValidationCheckStatusResultReason(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterValidationCheckStatusResultDetails(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterValidationCheckScenario(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalClusterEffectiveAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandGkeonpremBareMetalClusterAdminClusterMembership(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterBareMetalVersion(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterNetworkConfig(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{}) + + transformedIslandModeCidr, err := expandGkeonpremBareMetalClusterNetworkConfigIslandModeCidr(original["island_mode_cidr"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIslandModeCidr); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["islandModeCidr"] = transformedIslandModeCidr + } + + transformedAdvancedNetworking, err := expandGkeonpremBareMetalClusterNetworkConfigAdvancedNetworking(original["advanced_networking"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAdvancedNetworking); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["advancedNetworking"] = transformedAdvancedNetworking + } + + transformedMultipleNetworkInterfacesConfig, err := expandGkeonpremBareMetalClusterNetworkConfigMultipleNetworkInterfacesConfig(original["multiple_network_interfaces_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMultipleNetworkInterfacesConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["multipleNetworkInterfacesConfig"] = transformedMultipleNetworkInterfacesConfig + } + + transformedSrIovConfig, err := expandGkeonpremBareMetalClusterNetworkConfigSrIovConfig(original["sr_iov_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSrIovConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["srIovConfig"] = transformedSrIovConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterNetworkConfigIslandModeCidr(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{}) + + transformedServiceAddressCidrBlocks, err := expandGkeonpremBareMetalClusterNetworkConfigIslandModeCidrServiceAddressCidrBlocks(original["service_address_cidr_blocks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedServiceAddressCidrBlocks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["serviceAddressCidrBlocks"] = transformedServiceAddressCidrBlocks + } + + transformedPodAddressCidrBlocks, err := expandGkeonpremBareMetalClusterNetworkConfigIslandModeCidrPodAddressCidrBlocks(original["pod_address_cidr_blocks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPodAddressCidrBlocks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["podAddressCidrBlocks"] = transformedPodAddressCidrBlocks + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterNetworkConfigIslandModeCidrServiceAddressCidrBlocks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterNetworkConfigIslandModeCidrPodAddressCidrBlocks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterNetworkConfigAdvancedNetworking(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterNetworkConfigMultipleNetworkInterfacesConfig(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{}) + + transformedEnabled, err := expandGkeonpremBareMetalClusterNetworkConfigMultipleNetworkInterfacesConfigEnabled(original["enabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["enabled"] = transformedEnabled + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterNetworkConfigMultipleNetworkInterfacesConfigEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterNetworkConfigSrIovConfig(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{}) + + transformedEnabled, err := expandGkeonpremBareMetalClusterNetworkConfigSrIovConfigEnabled(original["enabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["enabled"] = transformedEnabled + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterNetworkConfigSrIovConfigEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterControlPlane(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{}) + + transformedControlPlaneNodePoolConfig, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfig(original["control_plane_node_pool_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneNodePoolConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneNodePoolConfig"] = transformedControlPlaneNodePoolConfig + } + + transformedApiServerArgs, err := expandGkeonpremBareMetalClusterControlPlaneApiServerArgs(original["api_server_args"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedApiServerArgs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["apiServerArgs"] = transformedApiServerArgs + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfig(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{}) + + transformedNodePoolConfig, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfig(original["node_pool_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodePoolConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodePoolConfig"] = transformedNodePoolConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfig(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{}) + + transformedNodeConfigs, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigs(original["node_configs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodeConfigs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodeConfigs"] = transformedNodeConfigs + } + + transformedOperatingSystem, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigOperatingSystem(original["operating_system"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOperatingSystem); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["operatingSystem"] = transformedOperatingSystem + } + + transformedTaints, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaints(original["taints"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTaints); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["taints"] = transformedTaints + } + + transformedLabels, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigs(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{}) + + transformedNodeIp, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsNodeIp(original["node_ip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodeIp); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodeIp"] = transformedNodeIp + } + + transformedLabels, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsNodeIp(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigNodeConfigsLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigOperatingSystem(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaints(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{}) + + transformedKey, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedValue, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["value"] = transformedValue + } + + transformedEffect, err := expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsEffect(original["effect"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEffect); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["effect"] = transformedEffect + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsValue(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigTaintsEffect(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneControlPlaneNodePoolConfigNodePoolConfigLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneApiServerArgs(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{}) + + transformedArgument, err := expandGkeonpremBareMetalClusterControlPlaneApiServerArgsArgument(original["argument"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedArgument); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["argument"] = transformedArgument + } + + transformedValue, err := expandGkeonpremBareMetalClusterControlPlaneApiServerArgsValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["value"] = transformedValue + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneApiServerArgsArgument(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterControlPlaneApiServerArgsValue(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancer(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{}) + + transformedVipConfig, err := expandGkeonpremBareMetalClusterLoadBalancerVipConfig(original["vip_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVipConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vipConfig"] = transformedVipConfig + } + + transformedPortConfig, err := expandGkeonpremBareMetalClusterLoadBalancerPortConfig(original["port_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPortConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["portConfig"] = transformedPortConfig + } + + transformedMetalLbConfig, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfig(original["metal_lb_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMetalLbConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["metalLbConfig"] = transformedMetalLbConfig + } + + transformedManualLbConfig, err := expandGkeonpremBareMetalClusterLoadBalancerManualLbConfig(original["manual_lb_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedManualLbConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["manualLbConfig"] = transformedManualLbConfig + } + + transformedBgpLbConfig, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfig(original["bgp_lb_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedBgpLbConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["bgpLbConfig"] = transformedBgpLbConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerVipConfig(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{}) + + transformedControlPlaneVip, err := expandGkeonpremBareMetalClusterLoadBalancerVipConfigControlPlaneVip(original["control_plane_vip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneVip); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneVip"] = transformedControlPlaneVip + } + + transformedIngressVip, err := expandGkeonpremBareMetalClusterLoadBalancerVipConfigIngressVip(original["ingress_vip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIngressVip); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ingressVip"] = transformedIngressVip + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerVipConfigControlPlaneVip(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerVipConfigIngressVip(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerPortConfig(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{}) + + transformedControlPlaneLoadBalancerPort, err := expandGkeonpremBareMetalClusterLoadBalancerPortConfigControlPlaneLoadBalancerPort(original["control_plane_load_balancer_port"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneLoadBalancerPort); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneLoadBalancerPort"] = transformedControlPlaneLoadBalancerPort + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerPortConfigControlPlaneLoadBalancerPort(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfig(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{}) + + transformedAddressPools, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPools(original["address_pools"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAddressPools); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["addressPools"] = transformedAddressPools + } + + transformedLoadBalancerNodePoolConfig, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfig(original["load_balancer_node_pool_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLoadBalancerNodePoolConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["loadBalancerNodePoolConfig"] = transformedLoadBalancerNodePoolConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPools(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{}) + + transformedPool, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsPool(original["pool"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPool); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["pool"] = transformedPool + } + + transformedAddresses, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsAddresses(original["addresses"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAddresses); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["addresses"] = transformedAddresses + } + + transformedAvoidBuggyIps, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsAvoidBuggyIps(original["avoid_buggy_ips"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAvoidBuggyIps); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["avoidBuggyIps"] = transformedAvoidBuggyIps + } + + transformedManualAssign, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsManualAssign(original["manual_assign"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedManualAssign); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["manualAssign"] = transformedManualAssign + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsPool(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsAddresses(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsAvoidBuggyIps(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigAddressPoolsManualAssign(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfig(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{}) + + transformedNodePoolConfig, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfig(original["node_pool_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodePoolConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodePoolConfig"] = transformedNodePoolConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfig(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{}) + + transformedNodeConfigs, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigs(original["node_configs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodeConfigs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodeConfigs"] = transformedNodeConfigs + } + + transformedOperatingSystem, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigOperatingSystem(original["operating_system"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOperatingSystem); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["operatingSystem"] = transformedOperatingSystem + } + + transformedTaints, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaints(original["taints"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTaints); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["taints"] = transformedTaints + } + + transformedLabels, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigs(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{}) + + transformedNodeIp, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsNodeIp(original["node_ip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodeIp); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodeIp"] = transformedNodeIp + } + + transformedLabels, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsNodeIp(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigOperatingSystem(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaints(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{}) + + transformedKey, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedValue, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["value"] = transformedValue + } + + transformedEffect, err := expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsEffect(original["effect"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEffect); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["effect"] = transformedEffect + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsValue(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsEffect(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerMetalLbConfigLoadBalancerNodePoolConfigNodePoolConfigLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerManualLbConfig(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{}) + + transformedEnabled, err := expandGkeonpremBareMetalClusterLoadBalancerManualLbConfigEnabled(original["enabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["enabled"] = transformedEnabled + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerManualLbConfigEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfig(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{}) + + transformedAsn, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAsn(original["asn"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAsn); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["asn"] = transformedAsn + } + + transformedBgpPeerConfigs, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigs(original["bgp_peer_configs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedBgpPeerConfigs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["bgpPeerConfigs"] = transformedBgpPeerConfigs + } + + transformedAddressPools, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPools(original["address_pools"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAddressPools); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["addressPools"] = transformedAddressPools + } + + transformedLoadBalancerNodePoolConfig, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfig(original["load_balancer_node_pool_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLoadBalancerNodePoolConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["loadBalancerNodePoolConfig"] = transformedLoadBalancerNodePoolConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAsn(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigs(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{}) + + transformedAsn, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsAsn(original["asn"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAsn); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["asn"] = transformedAsn + } + + transformedIpAddress, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsIpAddress(original["ip_address"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIpAddress); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ipAddress"] = transformedIpAddress + } + + transformedControlPlaneNodes, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsControlPlaneNodes(original["control_plane_nodes"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneNodes); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneNodes"] = transformedControlPlaneNodes + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsAsn(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsIpAddress(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigBgpPeerConfigsControlPlaneNodes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPools(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{}) + + transformedPool, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsPool(original["pool"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPool); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["pool"] = transformedPool + } + + transformedAddresses, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsAddresses(original["addresses"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAddresses); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["addresses"] = transformedAddresses + } + + transformedAvoidBuggyIps, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsAvoidBuggyIps(original["avoid_buggy_ips"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAvoidBuggyIps); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["avoidBuggyIps"] = transformedAvoidBuggyIps + } + + transformedManualAssign, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsManualAssign(original["manual_assign"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedManualAssign); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["manualAssign"] = transformedManualAssign + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsPool(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsAddresses(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsAvoidBuggyIps(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigAddressPoolsManualAssign(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfig(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{}) + + transformedNodePoolConfig, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfig(original["node_pool_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodePoolConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodePoolConfig"] = transformedNodePoolConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfig(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{}) + + transformedNodeConfigs, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigs(original["node_configs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodeConfigs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodeConfigs"] = transformedNodeConfigs + } + + transformedOperatingSystem, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigOperatingSystem(original["operating_system"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOperatingSystem); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["operatingSystem"] = transformedOperatingSystem + } + + transformedTaints, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaints(original["taints"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTaints); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["taints"] = transformedTaints + } + + transformedLabels, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + transformedKubeletConfig, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfig(original["kubelet_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKubeletConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["kubeletConfig"] = transformedKubeletConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigs(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{}) + + transformedNodeIp, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsNodeIp(original["node_ip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodeIp); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodeIp"] = transformedNodeIp + } + + transformedLabels, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsNodeIp(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigNodeConfigsLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigOperatingSystem(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaints(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{}) + + transformedKey, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedValue, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["value"] = transformedValue + } + + transformedEffect, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsEffect(original["effect"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEffect); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["effect"] = transformedEffect + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsValue(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigTaintsEffect(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfig(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{}) + + transformedRegistryPullQps, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigRegistryPullQps(original["registry_pull_qps"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedRegistryPullQps); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["registryPullQps"] = transformedRegistryPullQps + } + + transformedRegistryBurst, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigRegistryBurst(original["registry_burst"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedRegistryBurst); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["registryBurst"] = transformedRegistryBurst + } + + transformedSerializeImagePullsDisabled, err := expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigSerializeImagePullsDisabled(original["serialize_image_pulls_disabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSerializeImagePullsDisabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["serializeImagePullsDisabled"] = transformedSerializeImagePullsDisabled + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigRegistryPullQps(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigRegistryBurst(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterLoadBalancerBgpLbConfigLoadBalancerNodePoolConfigNodePoolConfigKubeletConfigSerializeImagePullsDisabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterStorage(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{}) + + transformedLvpShareConfig, err := expandGkeonpremBareMetalClusterStorageLvpShareConfig(original["lvp_share_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLvpShareConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["lvpShareConfig"] = transformedLvpShareConfig + } + + transformedLvpNodeMountsConfig, err := expandGkeonpremBareMetalClusterStorageLvpNodeMountsConfig(original["lvp_node_mounts_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLvpNodeMountsConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["lvpNodeMountsConfig"] = transformedLvpNodeMountsConfig + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterStorageLvpShareConfig(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{}) + + transformedLvpConfig, err := expandGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfig(original["lvp_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLvpConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["lvpConfig"] = transformedLvpConfig + } + + transformedSharedPathPvCount, err := expandGkeonpremBareMetalClusterStorageLvpShareConfigSharedPathPvCount(original["shared_path_pv_count"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSharedPathPvCount); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["sharedPathPvCount"] = transformedSharedPathPvCount + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfig(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{}) + + transformedPath, err := expandGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfigPath(original["path"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPath); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["path"] = transformedPath + } + + transformedStorageClass, err := expandGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfigStorageClass(original["storage_class"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStorageClass); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["storageClass"] = transformedStorageClass + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfigPath(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterStorageLvpShareConfigLvpConfigStorageClass(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterStorageLvpShareConfigSharedPathPvCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterStorageLvpNodeMountsConfig(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{}) + + transformedPath, err := expandGkeonpremBareMetalClusterStorageLvpNodeMountsConfigPath(original["path"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPath); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["path"] = transformedPath + } + + transformedStorageClass, err := expandGkeonpremBareMetalClusterStorageLvpNodeMountsConfigStorageClass(original["storage_class"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStorageClass); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["storageClass"] = transformedStorageClass + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterStorageLvpNodeMountsConfigPath(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterStorageLvpNodeMountsConfigStorageClass(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterProxy(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{}) + + transformedUri, err := expandGkeonpremBareMetalClusterProxyUri(original["uri"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUri); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["uri"] = transformedUri + } + + transformedNoProxy, err := expandGkeonpremBareMetalClusterProxyNoProxy(original["no_proxy"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNoProxy); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["noProxy"] = transformedNoProxy + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterProxyUri(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterProxyNoProxy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterClusterOperations(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{}) + + transformedEnableApplicationLogs, err := expandGkeonpremBareMetalClusterClusterOperationsEnableApplicationLogs(original["enable_application_logs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnableApplicationLogs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["enableApplicationLogs"] = transformedEnableApplicationLogs + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterClusterOperationsEnableApplicationLogs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterMaintenanceConfig(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{}) + + transformedMaintenanceAddressCidrBlocks, err := expandGkeonpremBareMetalClusterMaintenanceConfigMaintenanceAddressCidrBlocks(original["maintenance_address_cidr_blocks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaintenanceAddressCidrBlocks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["maintenanceAddressCidrBlocks"] = transformedMaintenanceAddressCidrBlocks + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterMaintenanceConfigMaintenanceAddressCidrBlocks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterNodeConfig(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{}) + + transformedMaxPodsPerNode, err := expandGkeonpremBareMetalClusterNodeConfigMaxPodsPerNode(original["max_pods_per_node"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxPodsPerNode); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["maxPodsPerNode"] = transformedMaxPodsPerNode + } + + transformedContainerRuntime, err := expandGkeonpremBareMetalClusterNodeConfigContainerRuntime(original["container_runtime"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedContainerRuntime); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["containerRuntime"] = transformedContainerRuntime + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterNodeConfigMaxPodsPerNode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterNodeConfigContainerRuntime(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterNodeAccessConfig(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{}) + + transformedLoginUser, err := expandGkeonpremBareMetalClusterNodeAccessConfigLoginUser(original["login_user"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLoginUser); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["loginUser"] = transformedLoginUser + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterNodeAccessConfigLoginUser(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterOsEnvironmentConfig(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{}) + + transformedPackageRepoExcluded, err := expandGkeonpremBareMetalClusterOsEnvironmentConfigPackageRepoExcluded(original["package_repo_excluded"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPackageRepoExcluded); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["packageRepoExcluded"] = transformedPackageRepoExcluded + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterOsEnvironmentConfigPackageRepoExcluded(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterSecurityConfig(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{}) + + transformedAuthorization, err := expandGkeonpremBareMetalClusterSecurityConfigAuthorization(original["authorization"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAuthorization); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["authorization"] = transformedAuthorization + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterSecurityConfigAuthorization(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{}) + + transformedAdminUsers, err := expandGkeonpremBareMetalClusterSecurityConfigAuthorizationAdminUsers(original["admin_users"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAdminUsers); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["adminUsers"] = transformedAdminUsers + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterSecurityConfigAuthorizationAdminUsers(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{}) + + transformedUsername, err := expandGkeonpremBareMetalClusterSecurityConfigAuthorizationAdminUsersUsername(original["username"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUsername); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["username"] = transformedUsername + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalClusterSecurityConfigAuthorizationAdminUsersUsername(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterBinaryAuthorization(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{}) + + transformedEvaluationMode, err := expandGkeonpremBareMetalClusterBinaryAuthorizationEvaluationMode(original["evaluation_mode"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEvaluationMode); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["evaluationMode"] = transformedEvaluationMode + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterBinaryAuthorizationEvaluationMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterUpgradePolicy(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{}) + + transformedPolicy, err := expandGkeonpremBareMetalClusterUpgradePolicyPolicy(original["policy"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPolicy); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["policy"] = transformedPolicy + } + + return transformed, nil +} + +func expandGkeonpremBareMetalClusterUpgradePolicyPolicy(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalClusterEffectiveAnnotations(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} diff --git a/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_generated_test.go b/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_generated_test.go new file mode 100644 index 00000000000..b8f7b109a08 --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_generated_test.go @@ -0,0 +1,424 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func TestAccGkeonpremBareMetalCluster_gkeonpremBareMetalClusterBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremBareMetalClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalCluster_gkeonpremBareMetalClusterBasicExample(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremBareMetalCluster_gkeonpremBareMetalClusterBasicExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_bare_metal_cluster" "cluster-basic" { + name = "tf-test-my-cluster%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/16"] + pod_address_cidr_blocks = ["10.240.0.0/13"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.9" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 443 + } + vip_config { + control_plane_vip = "10.200.0.13" + ingress_vip = "10.200.0.14" + } + metal_lb_config { + address_pools { + pool = "pool1" + addresses = [ + "10.200.0.14/32", + "10.200.0.15/32", + "10.200.0.16/32", + "10.200.0.17/32", + "10.200.0.18/32", + "fd00:1::f/128", + "fd00:1::10/128", + "fd00:1::11/128", + "fd00:1::12/128" + ] + avoid_buggy_ips = true + manual_assign = true + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 5 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } +} +`, context) +} + +func TestAccGkeonpremBareMetalCluster_gkeonpremBareMetalClusterManuallbExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremBareMetalClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalCluster_gkeonpremBareMetalClusterManuallbExample(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-manuallb", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremBareMetalCluster_gkeonpremBareMetalClusterManuallbExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_bare_metal_cluster" "cluster-manuallb" { + name = "tf-test-cluster-manuallb%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/16"] + pod_address_cidr_blocks = ["10.240.0.0/13"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.9" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 443 + } + vip_config { + control_plane_vip = "10.200.0.13" + ingress_vip = "10.200.0.14" + } + manual_lb_config { + enabled = true + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 5 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } + binary_authorization { + evaluation_mode = "DISABLED" + } + upgrade_policy { + policy = "SERIAL" + } +} +`, context) +} + +func TestAccGkeonpremBareMetalCluster_gkeonpremBareMetalClusterBgplbExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremBareMetalClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalCluster_gkeonpremBareMetalClusterBgplbExample(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-bgplb", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremBareMetalCluster_gkeonpremBareMetalClusterBgplbExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_bare_metal_cluster" "cluster-bgplb" { + name = "tf-test-cluster-bgplb%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/16"] + pod_address_cidr_blocks = ["10.240.0.0/13"] + } + advanced_networking = true + multiple_network_interfaces_config { + enabled = true + } + sr_iov_config { + enabled = true + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.9" + } + taints { + key = "test-key" + value = "test-value" + effect = "NO_EXECUTE" + } + } + } + api_server_args { + argument = "test-argument" + value = "test-value" + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 443 + } + vip_config { + control_plane_vip = "10.200.0.13" + ingress_vip = "10.200.0.14" + } + bgp_lb_config { + asn = 123456 + bgp_peer_configs { + asn = 123457 + ip_address = "10.0.0.1" + control_plane_nodes = ["test-node"] + } + address_pools { + pool = "pool1" + addresses = [ + "10.200.0.14/32", + "10.200.0.15/32", + "10.200.0.16/32", + "10.200.0.17/32", + "10.200.0.18/32", + "fd00:1::f/128", + "fd00:1::10/128", + "fd00:1::11/128", + "fd00:1::12/128" + ] + } + load_balancer_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.9" + } + taints { + key = "test-key" + value = "test-value" + effect = "NO_EXECUTE" + } + kubelet_config { + registry_pull_qps = 10 + registry_burst = 12 + serialize_image_pulls_disabled = true + } + } + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 5 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } + proxy { + uri = "http://test-domain/test" + no_proxy = ["127.0.0.1"] + } + cluster_operations { + enable_application_logs = true + } + maintenance_config { + maintenance_address_cidr_blocks = ["192.168.0.1/20"] + } + node_config { + max_pods_per_node = 10 + container_runtime = "CONTAINERD" + } + node_access_config { + login_user = "test@example.com" + } + os_environment_config { + package_repo_excluded = true + } +} +`, context) +} + +func testAccCheckGkeonpremBareMetalClusterDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_gkeonprem_bare_metal_cluster" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalClusters/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("GkeonpremBareMetalCluster still exists at %s", url) + } + } + + return nil + } +} diff --git a/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_sweeper.go b/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_sweeper.go new file mode 100644 index 00000000000..6d0cf9a0185 --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_sweeper.go @@ -0,0 +1,139 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem + +import ( + "context" + "log" + "strings" + "testing" + + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/sweeper" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func init() { + sweeper.AddTestSweepers("GkeonpremBareMetalCluster", testSweepGkeonpremBareMetalCluster) +} + +// At the time of writing, the CI only passes us-central1 as the region +func testSweepGkeonpremBareMetalCluster(region string) error { + resourceName := "GkeonpremBareMetalCluster" + log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) + + config, err := sweeper.SharedConfigForRegion(region) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) + return err + } + + err = config.LoadAndValidate(context.Background()) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) + return err + } + + t := &testing.T{} + billingId := envvar.GetTestBillingAccountFromEnv(t) + + // Setup variables to replace in list template + d := &tpgresource.ResourceDataMock{ + FieldsInSchema: map[string]interface{}{ + "project": config.Project, + "region": region, + "location": region, + "zone": "-", + "billing_account": billingId, + }, + } + + listTemplate := strings.Split("https://gkeonprem.googleapis.com/v1/projects/{{project}}/locations/{{location}}/bareMetalClusters", "?")[0] + listUrl, err := tpgresource.ReplaceVars(d, config, listTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) + return nil + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: config.Project, + RawURL: listUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) + return nil + } + + resourceList, ok := res["bareMetalClusters"] + if !ok { + log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") + return nil + } + + rl := resourceList.([]interface{}) + + log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) + // Keep count of items that aren't sweepable for logging. + nonPrefixCount := 0 + for _, ri := range rl { + obj := ri.(map[string]interface{}) + if obj["name"] == nil { + log.Printf("[INFO][SWEEPER_LOG] %s resource name was nil", resourceName) + return nil + } + + name := tpgresource.GetResourceNameFromSelfLink(obj["name"].(string)) + // Skip resources that shouldn't be sweeped + if !sweeper.IsSweepableTestResource(name) { + nonPrefixCount++ + continue + } + + deleteTemplate := "https://gkeonprem.googleapis.com/v1/projects/{{project}}/locations/{{location}}/bareMetalClusters/{{name}}?force=true" + deleteUrl, err := tpgresource.ReplaceVars(d, config, deleteTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) + return nil + } + deleteUrl = deleteUrl + name + + // Don't wait on operations as we may have a lot to delete + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: config.Project, + RawURL: deleteUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) + } else { + log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) + } + } + + if nonPrefixCount > 0 { + log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) + } + + return nil +} diff --git a/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_test.go b/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_test.go index 0ad9b6a9bdd..bdd17e68834 100644 --- a/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_test.go +++ b/google/services/gkeonprem/resource_gkeonprem_bare_metal_cluster_test.go @@ -1,3 +1,577 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package gkeonprem_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccGkeonpremBareMetalCluster_bareMetalClusterUpdateBasic(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremBareMetalClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateMetalLbStart(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-metallb", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, + }, + { + Config: testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateMetalLb(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-metallb", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, + }, + }, + }) +} + +func TestAccGkeonpremBareMetalCluster_bareMetalClusterUpdateManualLb(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremBareMetalClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateManualLbStart(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-manuallb", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateManualLb(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-manuallb", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGkeonpremBareMetalCluster_bareMetalClusterUpdateBgpLb(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremBareMetalClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateBgpLbStart(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-bgplb", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateBgpLb(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_cluster.cluster-bgplb", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateMetalLbStart(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_bare_metal_cluster" "cluster-metallb" { + name = "cluster-metallb%{random_suffix}" + location = "us-west1" + annotations = { + env = "test" + } + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/16"] + pod_address_cidr_blocks = ["10.240.0.0/13"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.9" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 443 + } + vip_config { + control_plane_vip = "10.200.0.13" + ingress_vip = "10.200.0.14" + } + metal_lb_config { + address_pools { + pool = "pool1" + addresses = [ + "10.200.0.14/32", + "10.200.0.15/32", + "10.200.0.16/32", + "10.200.0.17/32", + "10.200.0.18/32", + "fd00:1::f/128", + "fd00:1::10/128", + "fd00:1::11/128", + "fd00:1::12/128" + ] + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 5 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } + } +`, context) +} + +func testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateMetalLb(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_bare_metal_cluster" "cluster-metallb" { + name = "cluster-metallb%{random_suffix}" + location = "us-west1" + annotations = { + env = "test-update" + } + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/20"] + pod_address_cidr_blocks = ["10.240.0.0/14"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.10" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 80 + } + vip_config { + control_plane_vip = "10.200.0.14" + ingress_vip = "10.200.0.15" + } + metal_lb_config { + address_pools { + pool = "pool2" + addresses = [ + "10.200.0.14/32", + "10.200.0.15/32", + "10.200.0.16/32", + "10.200.0.17/32", + "fd00:1::f/128", + "fd00:1::10/128", + "fd00:1::11/128" + ] + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share-updated" + storage_class = "local-shared-updated" + } + shared_path_pv_count = 6 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk-updated" + storage_class = "local-disks-updated" + } + } + security_config { + authorization { + admin_users { + username = "admin-updated@hashicorptest.com" + } + } + } + } +`, context) +} + +func testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateManualLbStart(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_bare_metal_cluster" "cluster-manuallb" { + name = "cluster-manuallb%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/20"] + pod_address_cidr_blocks = ["10.240.0.0/14"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.10" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 80 + } + vip_config { + control_plane_vip = "10.200.0.13" + ingress_vip = "10.200.0.14" + } + metal_lb_config { + address_pools { + pool = "pool2" + addresses = [ + "10.200.0.14/32", + "10.200.0.15/32", + "10.200.0.16/32", + "10.200.0.17/32", + "fd00:1::f/128", + "fd00:1::10/128", + "fd00:1::11/128" + ] + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 6 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } + binary_authorization { + evaluation_mode = "DISABLED" + } + upgrade_policy { + policy = "SERIAL" + } + } +`, context) +} + +func testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateManualLb(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_bare_metal_cluster" "cluster-manuallb" { + name = "cluster-manuallb%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/20"] + pod_address_cidr_blocks = ["10.240.0.0/14"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.10" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 80 + } + vip_config { + control_plane_vip = "10.200.0.14" + ingress_vip = "10.200.0.15" + } + manual_lb_config { + enabled = true + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share-updated" + storage_class = "local-shared-updated" + } + shared_path_pv_count = 6 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk-updated" + storage_class = "local-disks-updated" + } + } + security_config { + authorization { + admin_users { + username = "admin-updated@hashicorptest.com" + } + } + } + binary_authorization { + evaluation_mode = "PROJECT_SINGLETON_POLICY_ENFORCE" + } + upgrade_policy { + policy = "CONCURRENT" + } + } +`, context) +} + +func testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateBgpLbStart(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_bare_metal_cluster" "cluster-bgplb" { + name = "cluster-bgplb%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/20"] + pod_address_cidr_blocks = ["10.240.0.0/14"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.10" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 80 + } + vip_config { + control_plane_vip = "10.200.0.13" + ingress_vip = "10.200.0.14" + } + bgp_lb_config { + asn = 123456 + bgp_peer_configs { + asn = 123457 + ip_address = "10.0.0.1" + control_plane_nodes = ["test-node"] + } + address_pools { + pool = "pool1" + addresses = [ + "10.200.0.14/32", + "fd00:1::12/128" + ] + } + load_balancer_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.9" + } + } + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 6 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } + } +`, context) +} + +func testAccGkeonpremBareMetalCluster_bareMetalClusterUpdateBgpLb(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_bare_metal_cluster" "cluster-bgplb" { + name = "cluster-bgplb%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/20"] + pod_address_cidr_blocks = ["10.240.0.0/14"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.10" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 80 + } + vip_config { + control_plane_vip = "10.200.0.14" + ingress_vip = "10.200.0.15" + } + bgp_lb_config { + asn = 123457 + bgp_peer_configs { + asn = 123458 + ip_address = "10.0.0.2" + control_plane_nodes = ["test-node-updated"] + } + address_pools { + pool = "pool2" + addresses = [ + "10.200.0.15/32", + "fd00:1::16/128" + ] + } + load_balancer_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.11" + } + } + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share-updated" + storage_class = "local-shared-updated" + } + shared_path_pv_count = 6 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk-updated" + storage_class = "local-disks-updated" + } + } + security_config { + authorization { + admin_users { + username = "admin-updated@hashicorptest.com" + } + } + } + } +`, context) +} diff --git a/google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool.go b/google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool.go new file mode 100644 index 00000000000..f7fbb26ac7e --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool.go @@ -0,0 +1,991 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-provider-google/google/verify" +) + +func ResourceGkeonpremBareMetalNodePool() *schema.Resource { + return &schema.Resource{ + Create: resourceGkeonpremBareMetalNodePoolCreate, + Read: resourceGkeonpremBareMetalNodePoolRead, + Update: resourceGkeonpremBareMetalNodePoolUpdate, + Delete: resourceGkeonpremBareMetalNodePoolDelete, + + Importer: &schema.ResourceImporter{ + State: resourceGkeonpremBareMetalNodePoolImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Update: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + CustomizeDiff: customdiff.All( + tpgresource.SetAnnotationsDiff, + tpgresource.DefaultProviderProject, + ), + + Schema: map[string]*schema.Schema{ + "bare_metal_cluster": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName, + Description: `The cluster this node pool belongs to.`, + }, + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The location of the resource.`, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The bare metal node pool name.`, + }, + "node_pool_config": { + Type: schema.TypeList, + Required: true, + Description: `Node pool configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "node_configs": { + Type: schema.TypeList, + Required: true, + Description: `The list of machine addresses in the Bare Metal Node Pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "labels": { + Type: schema.TypeMap, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to +each node. These will added in addition to any default label(s) +that Kubernetes may apply to the node. In case of conflict in +label keys, the applied set may differ depending on the Kubernetes +version -- it's best to assume the behavior is undefined and +conflicts should be avoided. For more information, including usage +and the valid values, see: + http://kubernetes.io/v1.1/docs/user-guide/labels.html +An object containing a list of "key": value pairs. +Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "node_ip": { + Type: schema.TypeString, + Optional: true, + Description: `The default IPv4 address for SSH access and Kubernetes node. +Example: 192.168.0.1`, + }, + }, + }, + }, + "labels": { + Type: schema.TypeMap, + Computed: true, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to +each node. These will added in addition to any default label(s) +that Kubernetes may apply to the node. In case of conflict in +label keys, the applied set may differ depending on the Kubernetes +version -- it's best to assume the behavior is undefined and +conflicts should be avoided. For more information, including usage +and the valid values, see: + http://kubernetes.io/v1.1/docs/user-guide/labels.html +An object containing a list of "key": value pairs. +Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "operating_system": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: `Specifies the nodes operating system (default: LINUX).`, + }, + "taints": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: `The initial taints assigned to nodes of this node pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "effect": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.ValidateEnum([]string{"EFFECT_UNSPECIFIED", "PREFER_NO_SCHEDULE", "NO_EXECUTE", ""}), + Description: `Specifies the nodes operating system (default: LINUX). Possible values: ["EFFECT_UNSPECIFIED", "PREFER_NO_SCHEDULE", "NO_EXECUTE"]`, + }, + "key": { + Type: schema.TypeString, + Optional: true, + Description: `Key associated with the effect.`, + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: `Value associated with the effect.`, + }, + }, + }, + }, + }, + }, + }, + "annotations": { + Type: schema.TypeMap, + Optional: true, + Description: `Annotations on the Bare Metal Node Pool. +This field has the same restrictions as Kubernetes annotations. +The total size of all keys and values combined is limited to 256k. +Key can have 2 segments: prefix (optional) and name (required), +separated by a slash (/). +Prefix must be a DNS subdomain. +Name must be 63 characters or less, begin and end with alphanumerics, +with dashes (-), underscores (_), dots (.), and alphanumerics between. + + +**Note**: This field is non-authoritative, and will only manage the annotations present in your configuration. +Please refer to the field 'effective_annotations' for all of the annotations present on the resource.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "display_name": { + Type: schema.TypeString, + Optional: true, + Description: `The display name for the Bare Metal Node Pool.`, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was created, in RFC3339 text format.`, + }, + "delete_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was deleted, in RFC3339 text format.`, + }, + "effective_annotations": { + Type: schema.TypeMap, + Computed: true, + Description: `All of annotations (key/value pairs) present on the resource in GCP, including the annotations configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "etag": { + Type: schema.TypeString, + Computed: true, + Description: `This checksum is computed by the server based on the value of other +fields, and may be sent on update and delete requests to ensure the +client has an up-to-date value before proceeding. +Allows clients to perform consistent read-modify-writes +through optimistic concurrency control.`, + }, + "reconciling": { + Type: schema.TypeBool, + Computed: true, + Description: `If set, there are currently changes in flight to the Bare Metal User Cluster.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The current state of this cluster.`, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Description: `Specifies detailed node pool status.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "conditions": { + Type: schema.TypeList, + Computed: true, + Description: `ResourceConditions provide a standard mechanism for higher-level status reporting from user cluster controller.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "message": { + Type: schema.TypeString, + Optional: true, + Description: `Human-readable message indicating details about last transition.`, + }, + "reason": { + Type: schema.TypeString, + Optional: true, + Description: `Machine-readable message indicating details about last transition.`, + }, + "type": { + Type: schema.TypeString, + Optional: true, + Description: `Type of the condition. +(e.g., ClusterRunning, NodePoolRunning or ServerSidePreflightReady)`, + }, + "last_transition_time": { + Type: schema.TypeString, + Computed: true, + Description: `Last time the condition transit from one status to another.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The lifecycle state of the condition.`, + }, + }, + }, + }, + "error_message": { + Type: schema.TypeString, + Computed: true, + Description: `Human-friendly representation of the error message from the user cluster +controller. The error message can be temporary as the user cluster +controller creates a cluster or node pool. If the error message persists +for a longer period of time, it can be used to surface error message to +indicate real problems requiring user intervention.`, + }, + }, + }, + }, + "uid": { + Type: schema.TypeString, + Computed: true, + Description: `The unique identifier of the Bare Metal Node Pool.`, + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was last updated, in RFC3339 text format.`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + UseJSONNumber: true, + } +} + +func resourceGkeonpremBareMetalNodePoolCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + displayNameProp, err := expandGkeonpremBareMetalNodePoolDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + nodePoolConfigProp, err := expandGkeonpremBareMetalNodePoolNodePoolConfig(d.Get("node_pool_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_pool_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(nodePoolConfigProp)) && (ok || !reflect.DeepEqual(v, nodePoolConfigProp)) { + obj["nodePoolConfig"] = nodePoolConfigProp + } + annotationsProp, err := expandGkeonpremBareMetalNodePoolEffectiveAnnotations(d.Get("effective_annotations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_annotations"); !tpgresource.IsEmptyValue(reflect.ValueOf(annotationsProp)) && (ok || !reflect.DeepEqual(v, annotationsProp)) { + obj["annotations"] = annotationsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalClusters/{{bare_metal_cluster}}/bareMetalNodePools?bare_metal_node_pool_id={{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new BareMetalNodePool: %#v", obj) + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalNodePool: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "POST", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutCreate), + }) + if err != nil { + return fmt.Errorf("Error creating BareMetalNodePool: %s", err) + } + + // Store the ID now + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/bareMetalClusters/{{bare_metal_cluster}}/bareMetalNodePools/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + // Use the resource in the operation response to populate + // identity fields and d.Id() before read + var opRes map[string]interface{} + err = GkeonpremOperationWaitTimeWithResponse( + config, res, &opRes, project, "Creating BareMetalNodePool", userAgent, + d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error waiting to create BareMetalNodePool: %s", err) + } + + // This may have caused the ID to update - update it if so. + id, err = tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/bareMetalClusters/{{bare_metal_cluster}}/bareMetalNodePools/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating BareMetalNodePool %q: %#v", d.Id(), res) + + return resourceGkeonpremBareMetalNodePoolRead(d, meta) +} + +func resourceGkeonpremBareMetalNodePoolRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalClusters/{{bare_metal_cluster}}/bareMetalNodePools/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalNodePool: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("GkeonpremBareMetalNodePool %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + + if err := d.Set("display_name", flattenGkeonpremBareMetalNodePoolDisplayName(res["displayName"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("annotations", flattenGkeonpremBareMetalNodePoolAnnotations(res["annotations"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("node_pool_config", flattenGkeonpremBareMetalNodePoolNodePoolConfig(res["nodePoolConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("status", flattenGkeonpremBareMetalNodePoolStatus(res["status"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("uid", flattenGkeonpremBareMetalNodePoolUid(res["uid"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("state", flattenGkeonpremBareMetalNodePoolState(res["state"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("reconciling", flattenGkeonpremBareMetalNodePoolReconciling(res["reconciling"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("create_time", flattenGkeonpremBareMetalNodePoolCreateTime(res["createTime"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("update_time", flattenGkeonpremBareMetalNodePoolUpdateTime(res["updateTime"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("delete_time", flattenGkeonpremBareMetalNodePoolDeleteTime(res["deleteTime"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("etag", flattenGkeonpremBareMetalNodePoolEtag(res["etag"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + if err := d.Set("effective_annotations", flattenGkeonpremBareMetalNodePoolEffectiveAnnotations(res["annotations"], d, config)); err != nil { + return fmt.Errorf("Error reading BareMetalNodePool: %s", err) + } + + return nil +} + +func resourceGkeonpremBareMetalNodePoolUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalNodePool: %s", err) + } + billingProject = project + + obj := make(map[string]interface{}) + displayNameProp, err := expandGkeonpremBareMetalNodePoolDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + nodePoolConfigProp, err := expandGkeonpremBareMetalNodePoolNodePoolConfig(d.Get("node_pool_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_pool_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nodePoolConfigProp)) { + obj["nodePoolConfig"] = nodePoolConfigProp + } + annotationsProp, err := expandGkeonpremBareMetalNodePoolEffectiveAnnotations(d.Get("effective_annotations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_annotations"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, annotationsProp)) { + obj["annotations"] = annotationsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalClusters/{{bare_metal_cluster}}/bareMetalNodePools/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating BareMetalNodePool %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("display_name") { + updateMask = append(updateMask, "displayName") + } + + if d.HasChange("node_pool_config") { + updateMask = append(updateMask, "nodePoolConfig") + } + + if d.HasChange("effective_annotations") { + updateMask = append(updateMask, "annotations") + } + // updateMask is a URL parameter but not present in the schema, so ReplaceVars + // won't set it + url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + // if updateMask is empty we are not updating anything so skip the post + if len(updateMask) > 0 { + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "PATCH", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutUpdate), + }) + + if err != nil { + return fmt.Errorf("Error updating BareMetalNodePool %q: %s", d.Id(), err) + } else { + log.Printf("[DEBUG] Finished updating BareMetalNodePool %q: %#v", d.Id(), res) + } + + err = GkeonpremOperationWaitTime( + config, res, project, "Updating BareMetalNodePool", userAgent, + d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return err + } + } + + return resourceGkeonpremBareMetalNodePoolRead(d, meta) +} + +func resourceGkeonpremBareMetalNodePoolDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for BareMetalNodePool: %s", err) + } + billingProject = project + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalClusters/{{bare_metal_cluster}}/bareMetalNodePools/{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting BareMetalNodePool %q", d.Id()) + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutDelete), + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, "BareMetalNodePool") + } + + err = GkeonpremOperationWaitTime( + config, res, project, "Deleting BareMetalNodePool", userAgent, + d.Timeout(schema.TimeoutDelete)) + + if err != nil { + return err + } + + log.Printf("[DEBUG] Finished deleting BareMetalNodePool %q: %#v", d.Id(), res) + return nil +} + +func resourceGkeonpremBareMetalNodePoolImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*transport_tpg.Config) + if err := tpgresource.ParseImportId([]string{ + "^projects/(?P[^/]+)/locations/(?P[^/]+)/bareMetalClusters/(?P[^/]+)/bareMetalNodePools/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)$", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/bareMetalClusters/{{bare_metal_cluster}}/bareMetalNodePools/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenGkeonpremBareMetalNodePoolDisplayName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("annotations"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenGkeonpremBareMetalNodePoolNodePoolConfig(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["node_configs"] = + flattenGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigs(original["nodeConfigs"], d, config) + transformed["operating_system"] = + flattenGkeonpremBareMetalNodePoolNodePoolConfigOperatingSystem(original["operatingSystem"], d, config) + transformed["taints"] = + flattenGkeonpremBareMetalNodePoolNodePoolConfigTaints(original["taints"], d, config) + transformed["labels"] = + flattenGkeonpremBareMetalNodePoolNodePoolConfigLabels(original["labels"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigs(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{}{ + "node_ip": flattenGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigsNodeIp(original["nodeIp"], d, config), + "labels": flattenGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigsLabels(original["labels"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigsNodeIp(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigsLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolNodePoolConfigOperatingSystem(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolNodePoolConfigTaints(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{}{ + "key": flattenGkeonpremBareMetalNodePoolNodePoolConfigTaintsKey(original["key"], d, config), + "value": flattenGkeonpremBareMetalNodePoolNodePoolConfigTaintsValue(original["value"], d, config), + "effect": flattenGkeonpremBareMetalNodePoolNodePoolConfigTaintsEffect(original["effect"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalNodePoolNodePoolConfigTaintsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolNodePoolConfigTaintsValue(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolNodePoolConfigTaintsEffect(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolNodePoolConfigLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolStatus(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["error_message"] = + flattenGkeonpremBareMetalNodePoolStatusErrorMessage(original["errorMessage"], d, config) + transformed["conditions"] = + flattenGkeonpremBareMetalNodePoolStatusConditions(original["conditions"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremBareMetalNodePoolStatusErrorMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolStatusConditions(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{}{ + "type": flattenGkeonpremBareMetalNodePoolStatusConditionsType(original["type"], d, config), + "reason": flattenGkeonpremBareMetalNodePoolStatusConditionsReason(original["reason"], d, config), + "message": flattenGkeonpremBareMetalNodePoolStatusConditionsMessage(original["message"], d, config), + "last_transition_time": flattenGkeonpremBareMetalNodePoolStatusConditionsLastTransitionTime(original["lastTransitionTime"], d, config), + "state": flattenGkeonpremBareMetalNodePoolStatusConditionsState(original["state"], d, config), + }) + } + return transformed +} +func flattenGkeonpremBareMetalNodePoolStatusConditionsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolStatusConditionsReason(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolStatusConditionsMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolStatusConditionsLastTransitionTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolStatusConditionsState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolUid(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolReconciling(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolUpdateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolDeleteTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolEtag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremBareMetalNodePoolEffectiveAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandGkeonpremBareMetalNodePoolDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalNodePoolNodePoolConfig(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{}) + + transformedNodeConfigs, err := expandGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigs(original["node_configs"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodeConfigs); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodeConfigs"] = transformedNodeConfigs + } + + transformedOperatingSystem, err := expandGkeonpremBareMetalNodePoolNodePoolConfigOperatingSystem(original["operating_system"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOperatingSystem); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["operatingSystem"] = transformedOperatingSystem + } + + transformedTaints, err := expandGkeonpremBareMetalNodePoolNodePoolConfigTaints(original["taints"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTaints); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["taints"] = transformedTaints + } + + transformedLabels, err := expandGkeonpremBareMetalNodePoolNodePoolConfigLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + return transformed, nil +} + +func expandGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigs(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{}) + + transformedNodeIp, err := expandGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigsNodeIp(original["node_ip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNodeIp); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["nodeIp"] = transformedNodeIp + } + + transformedLabels, err := expandGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigsLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigsNodeIp(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalNodePoolNodePoolConfigNodeConfigsLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremBareMetalNodePoolNodePoolConfigOperatingSystem(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalNodePoolNodePoolConfigTaints(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{}) + + transformedKey, err := expandGkeonpremBareMetalNodePoolNodePoolConfigTaintsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedValue, err := expandGkeonpremBareMetalNodePoolNodePoolConfigTaintsValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["value"] = transformedValue + } + + transformedEffect, err := expandGkeonpremBareMetalNodePoolNodePoolConfigTaintsEffect(original["effect"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEffect); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["effect"] = transformedEffect + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremBareMetalNodePoolNodePoolConfigTaintsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalNodePoolNodePoolConfigTaintsValue(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalNodePoolNodePoolConfigTaintsEffect(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremBareMetalNodePoolNodePoolConfigLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremBareMetalNodePoolEffectiveAnnotations(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} diff --git a/google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_generated_test.go b/google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_generated_test.go new file mode 100644 index 00000000000..8b283549fcc --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_generated_test.go @@ -0,0 +1,301 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func TestAccGkeonpremBareMetalNodePool_gkeonpremBareMetalNodePoolBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremBareMetalNodePoolDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalNodePool_gkeonpremBareMetalNodePoolBasicExample(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_node_pool.nodepool-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "bare_metal_cluster", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremBareMetalNodePool_gkeonpremBareMetalNodePoolBasicExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_bare_metal_cluster" "default-basic" { + name = "tf-test-my-cluster%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/16"] + pod_address_cidr_blocks = ["10.240.0.0/13"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.9" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 443 + } + vip_config { + control_plane_vip = "10.200.0.13" + ingress_vip = "10.200.0.14" + } + metal_lb_config { + address_pools { + pool = "pool1" + addresses = [ + "10.200.0.14/32", + "10.200.0.15/32", + "10.200.0.16/32", + "10.200.0.17/32", + "10.200.0.18/32", + "fd00:1::f/128", + "fd00:1::10/128", + "fd00:1::11/128", + "fd00:1::12/128" + ] + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 5 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } +} + +resource "google_gkeonprem_bare_metal_node_pool" "nodepool-basic" { + name = "tf-test-my-nodepool%{random_suffix}" + bare_metal_cluster = google_gkeonprem_bare_metal_cluster.default-basic.name + location = "us-west1" + node_pool_config { + operating_system = "LINUX" + node_configs { + node_ip = "10.200.0.11" + } + } +} +`, context) +} + +func TestAccGkeonpremBareMetalNodePool_gkeonpremBareMetalNodePoolFullExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremBareMetalNodePoolDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalNodePool_gkeonpremBareMetalNodePoolFullExample(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_node_pool.nodepool-full", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "bare_metal_cluster", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremBareMetalNodePool_gkeonpremBareMetalNodePoolFullExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_bare_metal_cluster" "default-full" { + name = "tf-test-my-cluster%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/16"] + pod_address_cidr_blocks = ["10.240.0.0/13"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.9" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 443 + } + vip_config { + control_plane_vip = "10.200.0.13" + ingress_vip = "10.200.0.14" + } + metal_lb_config { + address_pools { + pool = "pool1" + addresses = [ + "10.200.0.14/32", + "10.200.0.15/32", + "10.200.0.16/32", + "10.200.0.17/32", + "10.200.0.18/32", + "fd00:1::f/128", + "fd00:1::10/128", + "fd00:1::11/128", + "fd00:1::12/128" + ] + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 5 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } +} + +resource "google_gkeonprem_bare_metal_node_pool" "nodepool-full" { + name = "tf-test-my-nodepool%{random_suffix}" + display_name = "test-name" + bare_metal_cluster = google_gkeonprem_bare_metal_cluster.default-full.name + location = "us-west1" + annotations = {} + node_pool_config { + operating_system = "LINUX" + labels = {} + node_configs { + node_ip = "10.200.0.11" + labels = {} + } + taints { + key = "test-key" + value = "test-value" + effect = "NO_EXECUTE" + } + } +} +`, context) +} + +func testAccCheckGkeonpremBareMetalNodePoolDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_gkeonprem_bare_metal_node_pool" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/bareMetalClusters/{{bare_metal_cluster}}/bareMetalNodePools/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("GkeonpremBareMetalNodePool still exists at %s", url) + } + } + + return nil + } +} diff --git a/google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_test.go b/google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_test.go index 0ad9b6a9bdd..2d263ea75ec 100644 --- a/google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_test.go +++ b/google/services/gkeonprem/resource_gkeonprem_bare_metal_node_pool_test.go @@ -1,3 +1,228 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package gkeonprem_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccGkeonpremBareMetalNodePool_bareMetalNodePoolUpdate(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremBareMetalNodePoolDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremBareMetalNodePool_bareMetalNodePoolUpdateStart(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_node_pool.nodepool", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, + }, + { + Config: testAccGkeonpremBareMetalNodePool_bareMetalNodePoolUpdate(context), + }, + { + ResourceName: "google_gkeonprem_bare_metal_node_pool.nodepool", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, + }, + }, + }) +} + +func testAccGkeonpremBareMetalNodePool_bareMetalNodePoolUpdateStart(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_bare_metal_cluster" "cluster" { + name = "tf-test-cluster-%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/16"] + pod_address_cidr_blocks = ["10.240.0.0/13"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.9" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 443 + } + vip_config { + control_plane_vip = "10.200.0.13" + ingress_vip = "10.200.0.14" + } + metal_lb_config { + address_pools { + pool = "pool1" + addresses = [ + "10.200.0.14/32", + "10.200.0.15/32", + "10.200.0.16/32", + "10.200.0.17/32", + "10.200.0.18/32", + "fd00:1::f/128", + "fd00:1::10/128", + "fd00:1::11/128", + "fd00:1::12/128" + ] + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 5 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } + } + + resource "google_gkeonprem_bare_metal_node_pool" "nodepool" { + name = "tf-test-nodepool-%{random_suffix}" + location = "us-west1" + bare_metal_cluster = google_gkeonprem_bare_metal_cluster.cluster.name + annotations = { + env = "test" + } + node_pool_config { + operating_system = "LINUX" + labels = {} + node_configs { + node_ip = "10.200.0.11" + labels = {} + } + } + } +`, context) +} + +func testAccGkeonpremBareMetalNodePool_bareMetalNodePoolUpdate(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_bare_metal_cluster" "cluster" { + name = "tf-test-cluster-%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + bare_metal_version = "1.12.3" + network_config { + island_mode_cidr { + service_address_cidr_blocks = ["172.26.0.0/16"] + pod_address_cidr_blocks = ["10.240.0.0/13"] + } + } + control_plane { + control_plane_node_pool_config { + node_pool_config { + labels = {} + operating_system = "LINUX" + node_configs { + labels = {} + node_ip = "10.200.0.9" + } + } + } + } + load_balancer { + port_config { + control_plane_load_balancer_port = 443 + } + vip_config { + control_plane_vip = "10.200.0.13" + ingress_vip = "10.200.0.14" + } + metal_lb_config { + address_pools { + pool = "pool1" + addresses = [ + "10.200.0.14/32", + "10.200.0.15/32", + "10.200.0.16/32", + "10.200.0.17/32", + "10.200.0.18/32", + "fd00:1::f/128", + "fd00:1::10/128", + "fd00:1::11/128", + "fd00:1::12/128" + ] + } + } + } + storage { + lvp_share_config { + lvp_config { + path = "/mnt/localpv-share" + storage_class = "local-shared" + } + shared_path_pv_count = 5 + } + lvp_node_mounts_config { + path = "/mnt/localpv-disk" + storage_class = "local-disks" + } + } + security_config { + authorization { + admin_users { + username = "admin@hashicorptest.com" + } + } + } + } + + resource "google_gkeonprem_bare_metal_node_pool" "nodepool" { + name = "tf-test-nodepool-%{random_suffix}" + location = "us-west1" + bare_metal_cluster = google_gkeonprem_bare_metal_cluster.cluster.name + annotations = { + env = "test-update" + } + node_pool_config { + operating_system = "LINUX" + labels = {} + node_configs { + node_ip = "10.200.0.12" + labels = {} + } + } + } +`, context) +} diff --git a/google/services/gkeonprem/resource_gkeonprem_vmware_cluster.go b/google/services/gkeonprem/resource_gkeonprem_vmware_cluster.go new file mode 100644 index 00000000000..1307678f107 --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_vmware_cluster.go @@ -0,0 +1,3459 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func ResourceGkeonpremVmwareCluster() *schema.Resource { + return &schema.Resource{ + Create: resourceGkeonpremVmwareClusterCreate, + Read: resourceGkeonpremVmwareClusterRead, + Update: resourceGkeonpremVmwareClusterUpdate, + Delete: resourceGkeonpremVmwareClusterDelete, + + Importer: &schema.ResourceImporter{ + State: resourceGkeonpremVmwareClusterImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(60 * time.Minute), + Update: schema.DefaultTimeout(60 * time.Minute), + Delete: schema.DefaultTimeout(60 * time.Minute), + }, + + CustomizeDiff: customdiff.All( + tpgresource.SetAnnotationsDiff, + tpgresource.DefaultProviderProject, + ), + + Schema: map[string]*schema.Schema{ + "admin_cluster_membership": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: tpgresource.ProjectNumberDiffSuppress, + Description: `The admin cluster this VMware User Cluster belongs to. +This is the full resource name of the admin cluster's hub membership. +In the future, references to other resource types might be allowed if +admin clusters are modeled as their own resources.`, + }, + "control_plane_node": { + Type: schema.TypeList, + Required: true, + Description: `VMware User Cluster control plane nodes must have either 1 or 3 replicas.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "auto_resize_config": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: `AutoResizeConfig provides auto resizing configurations.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + Description: `Whether to enable control plane node auto resizing.`, + }, + }, + }, + }, + "cpus": { + Type: schema.TypeInt, + Optional: true, + Description: `The number of CPUs for each admin cluster node that serve as control planes +for this VMware User Cluster. (default: 4 CPUs)`, + Default: 4, + }, + "memory": { + Type: schema.TypeInt, + Optional: true, + Description: `The megabytes of memory for each admin cluster node that serves as a +control plane for this VMware User Cluster (default: 8192 MB memory).`, + Default: 8192, + }, + "replicas": { + Type: schema.TypeInt, + Optional: true, + Description: `The number of control plane nodes for this VMware User Cluster. +(default: 1 replica).`, + Default: 1, + }, + "vsphere_config": { + Type: schema.TypeList, + Computed: true, + Description: `Vsphere-specific config.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "datastore": { + Type: schema.TypeString, + Computed: true, + Description: `The Vsphere datastore used by the Control Plane Node.`, + }, + "storage_policy_name": { + Type: schema.TypeString, + Computed: true, + Description: `The Vsphere storage policy used by the control plane Node.`, + }, + }, + }, + }, + }, + }, + }, + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The location of the resource.`, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The VMware cluster name.`, + }, + "on_prem_version": { + Type: schema.TypeString, + Required: true, + Description: `The Anthos clusters on the VMware version for your user cluster.`, + }, + "annotations": { + Type: schema.TypeMap, + Optional: true, + Description: `Annotations on the VMware User Cluster. +This field has the same restrictions as Kubernetes annotations. +The total size of all keys and values combined is limited to 256k. +Key can have 2 segments: prefix (optional) and name (required), +separated by a slash (/). +Prefix must be a DNS subdomain. +Name must be 63 characters or less, begin and end with alphanumerics, +with dashes (-), underscores (_), dots (.), and alphanumerics between. + + +**Note**: This field is non-authoritative, and will only manage the annotations present in your configuration. +Please refer to the field 'effective_annotations' for all of the annotations present on the resource.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "anti_affinity_groups": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: `AAGConfig specifies whether to spread VMware User Cluster nodes across at +least three physical hosts in the datacenter.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "aag_config_disabled": { + Type: schema.TypeBool, + Required: true, + Description: `Spread nodes across at least three physical hosts (requires at least three +hosts). +Enabled by default.`, + }, + }, + }, + }, + "authorization": { + Type: schema.TypeList, + Optional: true, + Description: `RBAC policy that will be applied and managed by GKE On-Prem.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "admin_users": { + Type: schema.TypeList, + Optional: true, + Description: `Users that will be granted the cluster-admin role on the cluster, providing +full access to the cluster.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + Description: `The name of the user, e.g. 'my-gcp-id@gmail.com'.`, + }, + }, + }, + }, + }, + }, + }, + "auto_repair_config": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: `Configuration for auto repairing.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + Description: `Whether auto repair is enabled.`, + }, + }, + }, + }, + "dataplane_v2": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: `VmwareDataplaneV2Config specifies configuration for Dataplane V2.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "advanced_networking": { + Type: schema.TypeBool, + Optional: true, + Description: `Enable advanced networking which requires dataplane_v2_enabled to be set true.`, + }, + "dataplane_v2_enabled": { + Type: schema.TypeBool, + Optional: true, + Description: `Enables Dataplane V2.`, + }, + "windows_dataplane_v2_enabled": { + Type: schema.TypeBool, + Optional: true, + Description: `Enable Dataplane V2 for clusters with Windows nodes.`, + }, + }, + }, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: `A human readable description of this VMware User Cluster.`, + }, + "enable_control_plane_v2": { + Type: schema.TypeBool, + Optional: true, + Description: `Enable control plane V2. Default to false.`, + }, + "load_balancer": { + Type: schema.TypeList, + Optional: true, + Description: `Load Balancer configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "f5_config": { + Type: schema.TypeList, + Optional: true, + Description: `Configuration for F5 Big IP typed load balancers.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Optional: true, + Description: `The load balancer's IP address.`, + }, + "partition": { + Type: schema.TypeString, + Optional: true, + Description: `he preexisting partition to be used by the load balancer. T +his partition is usually created for the admin cluster for example: +'my-f5-admin-partition'.`, + }, + "snat_pool": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: `The pool name. Only necessary, if using SNAT.`, + }, + }, + }, + ExactlyOneOf: []string{"load_balancer.0.f5_config", "load_balancer.0.manual_lb_config", "load_balancer.0.metal_lb_config"}, + }, + "manual_lb_config": { + Type: schema.TypeList, + Optional: true, + Description: `Manually configured load balancers.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "control_plane_node_port": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: `NodePort for control plane service. The Kubernetes API server in the admin +cluster is implemented as a Service of type NodePort (ex. 30968).`, + }, + "ingress_http_node_port": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: `NodePort for ingress service's http. The ingress service in the admin +cluster is implemented as a Service of type NodePort (ex. 32527).`, + }, + "ingress_https_node_port": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: `NodePort for ingress service's https. The ingress service in the admin +cluster is implemented as a Service of type NodePort (ex. 30139).`, + }, + "konnectivity_server_node_port": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: `NodePort for konnectivity server service running as a sidecar in each +kube-apiserver pod (ex. 30564).`, + }, + }, + }, + ExactlyOneOf: []string{"load_balancer.0.f5_config", "load_balancer.0.manual_lb_config", "load_balancer.0.metal_lb_config"}, + }, + "metal_lb_config": { + Type: schema.TypeList, + Optional: true, + Description: `Configuration for MetalLB typed load balancers.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address_pools": { + Type: schema.TypeList, + Required: true, + Description: `AddressPools is a list of non-overlapping IP pools used by load balancer +typed services. All addresses must be routable to load balancer nodes. +IngressVIP must be included in the pools.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "addresses": { + Type: schema.TypeList, + Required: true, + Description: `The addresses that are part of this pool. Each address +must be either in the CIDR form (1.2.3.0/24) or range +form (1.2.3.1-1.2.3.5).`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "pool": { + Type: schema.TypeString, + Required: true, + Description: `The name of the address pool.`, + }, + "avoid_buggy_ips": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: `If true, avoid using IPs ending in .0 or .255. +This avoids buggy consumer devices mistakenly dropping IPv4 traffic for +those special IP addresses.`, + }, + "manual_assign": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: `If true, prevent IP addresses from being automatically assigned.`, + }, + }, + }, + }, + }, + }, + ExactlyOneOf: []string{"load_balancer.0.f5_config", "load_balancer.0.manual_lb_config", "load_balancer.0.metal_lb_config"}, + }, + "vip_config": { + Type: schema.TypeList, + Optional: true, + Description: `The VIPs used by the load balancer.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "control_plane_vip": { + Type: schema.TypeString, + Optional: true, + Description: `The VIP which you previously set aside for the Kubernetes API of this cluster.`, + }, + "ingress_vip": { + Type: schema.TypeString, + Optional: true, + Description: `The VIP which you previously set aside for ingress traffic into this cluster.`, + }, + }, + }, + }, + }, + }, + }, + "network_config": { + Type: schema.TypeList, + Optional: true, + Description: `The VMware User Cluster network configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "pod_address_cidr_blocks": { + Type: schema.TypeList, + Required: true, + Description: `All pods in the cluster are assigned an RFC1918 IPv4 address from these ranges. +Only a single range is supported. This field cannot be changed after creation.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "service_address_cidr_blocks": { + Type: schema.TypeList, + Required: true, + Description: `All services in the cluster are assigned an RFC1918 IPv4 address +from these ranges. Only a single range is supported.. This field +cannot be changed after creation.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "control_plane_v2_config": { + Type: schema.TypeList, + Optional: true, + Description: `Configuration for control plane V2 mode.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "control_plane_ip_block": { + Type: schema.TypeList, + Optional: true, + Description: `Static IP addresses for the control plane nodes.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "gateway": { + Type: schema.TypeString, + Optional: true, + Description: `The network gateway used by the VMware User Cluster.`, + }, + "ips": { + Type: schema.TypeList, + Optional: true, + Description: `The node's network configurations used by the VMware User Cluster.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "hostname": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: `Hostname of the machine. VM's name will be used if this field is empty.`, + }, + "ip": { + Type: schema.TypeString, + Optional: true, + Description: `IP could be an IP address (like 1.2.3.4) or a CIDR (like 1.2.3.0/24).`, + }, + }, + }, + }, + "netmask": { + Type: schema.TypeString, + Optional: true, + Description: `The netmask used by the VMware User Cluster.`, + }, + }, + }, + }, + }, + }, + }, + "dhcp_ip_config": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: `Configuration settings for a DHCP IP configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + Description: `enabled is a flag to mark if DHCP IP allocation is +used for VMware user clusters.`, + }, + }, + }, + ExactlyOneOf: []string{"network_config.0.static_ip_config", "network_config.0.dhcp_ip_config"}, + }, + "host_config": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: `Represents common network settings irrespective of the host's IP address.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns_search_domains": { + Type: schema.TypeList, + Optional: true, + Description: `DNS search domains.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "dns_servers": { + Type: schema.TypeList, + Optional: true, + Description: `DNS servers.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ntp_servers": { + Type: schema.TypeList, + Optional: true, + Description: `NTP servers.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "static_ip_config": { + Type: schema.TypeList, + Optional: true, + Description: `Configuration settings for a static IP configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_blocks": { + Type: schema.TypeList, + Required: true, + Description: `Represents the configuration values for static IP allocation to nodes.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "gateway": { + Type: schema.TypeString, + Required: true, + Description: `The network gateway used by the VMware User Cluster.`, + }, + "ips": { + Type: schema.TypeList, + Required: true, + Description: `The node's network configurations used by the VMware User Cluster.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Required: true, + Description: `IP could be an IP address (like 1.2.3.4) or a CIDR (like 1.2.3.0/24).`, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: `Hostname of the machine. VM's name will be used if this field is empty.`, + }, + }, + }, + }, + "netmask": { + Type: schema.TypeString, + Required: true, + Description: `The netmask used by the VMware User Cluster.`, + }, + }, + }, + }, + }, + }, + ExactlyOneOf: []string{"network_config.0.static_ip_config", "network_config.0.dhcp_ip_config"}, + }, + "vcenter_network": { + Type: schema.TypeString, + Computed: true, + Description: `vcenter_network specifies vCenter network name. Inherited from the admin cluster.`, + }, + }, + }, + }, + "storage": { + Type: schema.TypeList, + Computed: true, + Optional: true, + Description: `Storage configuration.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "vsphere_csi_disabled": { + Type: schema.TypeBool, + Required: true, + Description: `Whether or not to deploy vSphere CSI components in the VMware User Cluster. +Enabled by default.`, + }, + }, + }, + }, + "upgrade_policy": { + Type: schema.TypeList, + Optional: true, + Description: `Specifies upgrade policy for the cluster.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "control_plane_only": { + Type: schema.TypeBool, + Optional: true, + Description: `Controls whether the upgrade applies to the control plane only.`, + }, + }, + }, + }, + "vcenter": { + Type: schema.TypeList, + Optional: true, + Description: `VmwareVCenterConfig specifies vCenter config for the user cluster. +Inherited from the admin cluster.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ca_cert_data": { + Type: schema.TypeString, + Optional: true, + Description: `Contains the vCenter CA certificate public key for SSL verification.`, + }, + "cluster": { + Type: schema.TypeString, + Optional: true, + Description: `The name of the vCenter cluster for the user cluster.`, + }, + "datacenter": { + Type: schema.TypeString, + Optional: true, + Description: `The name of the vCenter datacenter for the user cluster.`, + }, + "datastore": { + Type: schema.TypeString, + Optional: true, + Description: `The name of the vCenter datastore for the user cluster.`, + }, + "folder": { + Type: schema.TypeString, + Optional: true, + Description: `The name of the vCenter folder for the user cluster.`, + }, + "resource_pool": { + Type: schema.TypeString, + Optional: true, + Description: `The name of the vCenter resource pool for the user cluster.`, + }, + "storage_policy_name": { + Type: schema.TypeString, + Optional: true, + Description: `The name of the vCenter storage policy for the user cluster.`, + }, + "address": { + Type: schema.TypeString, + Computed: true, + Description: `The vCenter IP address.`, + }, + }, + }, + }, + "vm_tracking_enabled": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: `Enable VM tracking.`, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time at which VMware User Cluster was created.`, + }, + "delete_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time at which VMware User Cluster was deleted.`, + }, + "effective_annotations": { + Type: schema.TypeMap, + Computed: true, + Description: `All of annotations (key/value pairs) present on the resource in GCP, including the annotations configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "endpoint": { + Type: schema.TypeString, + Computed: true, + Description: `The DNS name of VMware User Cluster's API server.`, + }, + "etag": { + Type: schema.TypeString, + Computed: true, + Description: `This checksum is computed by the server based on the value of other +fields, and may be sent on update and delete requests to ensure the +client has an up-to-date value before proceeding. +Allows clients to perform consistent read-modify-writes +through optimistic concurrency control.`, + }, + "fleet": { + Type: schema.TypeList, + Computed: true, + Description: `Fleet configuration for the cluster.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "membership": { + Type: schema.TypeString, + Computed: true, + Description: `The name of the managed Hub Membership resource associated to this cluster. +Membership names are formatted as +'projects//locations//memberships/'.`, + }, + }, + }, + }, + "local_name": { + Type: schema.TypeString, + Computed: true, + Description: `The object name of the VMware OnPremUserCluster custom resource on the +associated admin cluster. This field is used to support conflicting +names when enrolling existing clusters to the API. When used as a part of +cluster enrollment, this field will differ from the ID in the resource +name. For new clusters, this field will match the user provided cluster ID +and be visible in the last component of the resource name. It is not +modifiable. + +All users should use this name to access their cluster using gkectl or +kubectl and should expect to see the local name when viewing admin +cluster controller logs.`, + }, + "reconciling": { + Type: schema.TypeBool, + Computed: true, + Description: `If set, there are currently changes in flight to the VMware User Cluster.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The current state of this cluster.`, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Description: `ResourceStatus representing detailed cluster state.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "conditions": { + Type: schema.TypeList, + Computed: true, + Description: `ResourceConditions provide a standard mechanism for higher-level status reporting from user cluster controller.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "last_transition_time": { + Type: schema.TypeString, + Computed: true, + Description: `Last time the condition transit from one status to another.`, + }, + "message": { + Type: schema.TypeString, + Computed: true, + Description: `Human-readable message indicating details about last transition.`, + }, + "reason": { + Type: schema.TypeString, + Computed: true, + Description: `Machine-readable message indicating details about last transition.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The lifecycle state of the condition.`, + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: `Type of the condition. +(e.g., ClusterRunning, NodePoolRunning or ServerSidePreflightReady)`, + }, + }, + }, + }, + "error_message": { + Type: schema.TypeString, + Computed: true, + Description: `Human-friendly representation of the error message from the user cluster +controller. The error message can be temporary as the user cluster +controller creates a cluster or node pool. If the error message persists +for a longer period of time, it can be used to surface error message to +indicate real problems requiring user intervention.`, + }, + }, + }, + }, + "uid": { + Type: schema.TypeString, + Computed: true, + Description: `The unique identifier of the VMware User Cluster.`, + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time at which VMware User Cluster was last updated.`, + }, + "validation_check": { + Type: schema.TypeList, + Computed: true, + Description: `ValidationCheck represents the result of the preflight check job.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "options": { + Type: schema.TypeString, + Computed: true, + Description: `Options used for the validation check.`, + }, + "scenario": { + Type: schema.TypeString, + Computed: true, + Description: `The scenario when the preflight checks were run..`, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Description: `Specifies the detailed validation check status`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "result": { + Type: schema.TypeList, + Computed: true, + Description: `Individual checks which failed as part of the Preflight check execution.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "category": { + Type: schema.TypeString, + Computed: true, + Description: `The category of the validation.`, + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: `The description of the validation check.`, + }, + "details": { + Type: schema.TypeString, + Computed: true, + Description: `Detailed failure information, which might be unformatted.`, + }, + "options": { + Type: schema.TypeString, + Computed: true, + Description: `Options used for the validation check.`, + }, + "reason": { + Type: schema.TypeString, + Computed: true, + Description: `A human-readable message of the check failure.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + UseJSONNumber: true, + } +} + +func resourceGkeonpremVmwareClusterCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + adminClusterMembershipProp, err := expandGkeonpremVmwareClusterAdminClusterMembership(d.Get("admin_cluster_membership"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("admin_cluster_membership"); !tpgresource.IsEmptyValue(reflect.ValueOf(adminClusterMembershipProp)) && (ok || !reflect.DeepEqual(v, adminClusterMembershipProp)) { + obj["adminClusterMembership"] = adminClusterMembershipProp + } + descriptionProp, err := expandGkeonpremVmwareClusterDescription(d.Get("description"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + onPremVersionProp, err := expandGkeonpremVmwareClusterOnPremVersion(d.Get("on_prem_version"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("on_prem_version"); !tpgresource.IsEmptyValue(reflect.ValueOf(onPremVersionProp)) && (ok || !reflect.DeepEqual(v, onPremVersionProp)) { + obj["onPremVersion"] = onPremVersionProp + } + controlPlaneNodeProp, err := expandGkeonpremVmwareClusterControlPlaneNode(d.Get("control_plane_node"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("control_plane_node"); !tpgresource.IsEmptyValue(reflect.ValueOf(controlPlaneNodeProp)) && (ok || !reflect.DeepEqual(v, controlPlaneNodeProp)) { + obj["controlPlaneNode"] = controlPlaneNodeProp + } + antiAffinityGroupsProp, err := expandGkeonpremVmwareClusterAntiAffinityGroups(d.Get("anti_affinity_groups"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("anti_affinity_groups"); !tpgresource.IsEmptyValue(reflect.ValueOf(antiAffinityGroupsProp)) && (ok || !reflect.DeepEqual(v, antiAffinityGroupsProp)) { + obj["antiAffinityGroups"] = antiAffinityGroupsProp + } + storageProp, err := expandGkeonpremVmwareClusterStorage(d.Get("storage"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("storage"); !tpgresource.IsEmptyValue(reflect.ValueOf(storageProp)) && (ok || !reflect.DeepEqual(v, storageProp)) { + obj["storage"] = storageProp + } + networkConfigProp, err := expandGkeonpremVmwareClusterNetworkConfig(d.Get("network_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("network_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(networkConfigProp)) && (ok || !reflect.DeepEqual(v, networkConfigProp)) { + obj["networkConfig"] = networkConfigProp + } + loadBalancerProp, err := expandGkeonpremVmwareClusterLoadBalancer(d.Get("load_balancer"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("load_balancer"); !tpgresource.IsEmptyValue(reflect.ValueOf(loadBalancerProp)) && (ok || !reflect.DeepEqual(v, loadBalancerProp)) { + obj["loadBalancer"] = loadBalancerProp + } + dataplaneV2Prop, err := expandGkeonpremVmwareClusterDataplaneV2(d.Get("dataplane_v2"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("dataplane_v2"); !tpgresource.IsEmptyValue(reflect.ValueOf(dataplaneV2Prop)) && (ok || !reflect.DeepEqual(v, dataplaneV2Prop)) { + obj["dataplaneV2"] = dataplaneV2Prop + } + vmTrackingEnabledProp, err := expandGkeonpremVmwareClusterVmTrackingEnabled(d.Get("vm_tracking_enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("vm_tracking_enabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(vmTrackingEnabledProp)) && (ok || !reflect.DeepEqual(v, vmTrackingEnabledProp)) { + obj["vmTrackingEnabled"] = vmTrackingEnabledProp + } + autoRepairConfigProp, err := expandGkeonpremVmwareClusterAutoRepairConfig(d.Get("auto_repair_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("auto_repair_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(autoRepairConfigProp)) && (ok || !reflect.DeepEqual(v, autoRepairConfigProp)) { + obj["autoRepairConfig"] = autoRepairConfigProp + } + authorizationProp, err := expandGkeonpremVmwareClusterAuthorization(d.Get("authorization"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("authorization"); !tpgresource.IsEmptyValue(reflect.ValueOf(authorizationProp)) && (ok || !reflect.DeepEqual(v, authorizationProp)) { + obj["authorization"] = authorizationProp + } + enableControlPlaneV2Prop, err := expandGkeonpremVmwareClusterEnableControlPlaneV2(d.Get("enable_control_plane_v2"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enable_control_plane_v2"); !tpgresource.IsEmptyValue(reflect.ValueOf(enableControlPlaneV2Prop)) && (ok || !reflect.DeepEqual(v, enableControlPlaneV2Prop)) { + obj["enableControlPlaneV2"] = enableControlPlaneV2Prop + } + upgradePolicyProp, err := expandGkeonpremVmwareClusterUpgradePolicy(d.Get("upgrade_policy"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("upgrade_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(upgradePolicyProp)) && (ok || !reflect.DeepEqual(v, upgradePolicyProp)) { + obj["upgradePolicy"] = upgradePolicyProp + } + vcenterProp, err := expandGkeonpremVmwareClusterVcenter(d.Get("vcenter"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("vcenter"); !tpgresource.IsEmptyValue(reflect.ValueOf(vcenterProp)) && (ok || !reflect.DeepEqual(v, vcenterProp)) { + obj["vcenter"] = vcenterProp + } + annotationsProp, err := expandGkeonpremVmwareClusterEffectiveAnnotations(d.Get("effective_annotations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_annotations"); !tpgresource.IsEmptyValue(reflect.ValueOf(annotationsProp)) && (ok || !reflect.DeepEqual(v, annotationsProp)) { + obj["annotations"] = annotationsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/vmwareClusters?vmware_cluster_id={{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new VmwareCluster: %#v", obj) + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for VmwareCluster: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "POST", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutCreate), + }) + if err != nil { + return fmt.Errorf("Error creating VmwareCluster: %s", err) + } + + // Store the ID now + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/vmwareClusters/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + // Use the resource in the operation response to populate + // identity fields and d.Id() before read + var opRes map[string]interface{} + err = GkeonpremOperationWaitTimeWithResponse( + config, res, &opRes, project, "Creating VmwareCluster", userAgent, + d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error waiting to create VmwareCluster: %s", err) + } + + // This may have caused the ID to update - update it if so. + id, err = tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/vmwareClusters/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating VmwareCluster %q: %#v", d.Id(), res) + + return resourceGkeonpremVmwareClusterRead(d, meta) +} + +func resourceGkeonpremVmwareClusterRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/vmwareClusters/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for VmwareCluster: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("GkeonpremVmwareCluster %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + + if err := d.Set("admin_cluster_membership", flattenGkeonpremVmwareClusterAdminClusterMembership(res["adminClusterMembership"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("description", flattenGkeonpremVmwareClusterDescription(res["description"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("on_prem_version", flattenGkeonpremVmwareClusterOnPremVersion(res["onPremVersion"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("annotations", flattenGkeonpremVmwareClusterAnnotations(res["annotations"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("control_plane_node", flattenGkeonpremVmwareClusterControlPlaneNode(res["controlPlaneNode"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("anti_affinity_groups", flattenGkeonpremVmwareClusterAntiAffinityGroups(res["antiAffinityGroups"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("storage", flattenGkeonpremVmwareClusterStorage(res["storage"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("network_config", flattenGkeonpremVmwareClusterNetworkConfig(res["networkConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("load_balancer", flattenGkeonpremVmwareClusterLoadBalancer(res["loadBalancer"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("dataplane_v2", flattenGkeonpremVmwareClusterDataplaneV2(res["dataplaneV2"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("vm_tracking_enabled", flattenGkeonpremVmwareClusterVmTrackingEnabled(res["vmTrackingEnabled"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("auto_repair_config", flattenGkeonpremVmwareClusterAutoRepairConfig(res["autoRepairConfig"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("authorization", flattenGkeonpremVmwareClusterAuthorization(res["authorization"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("validation_check", flattenGkeonpremVmwareClusterValidationCheck(res["validationCheck"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("enable_control_plane_v2", flattenGkeonpremVmwareClusterEnableControlPlaneV2(res["enableControlPlaneV2"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("upgrade_policy", flattenGkeonpremVmwareClusterUpgradePolicy(res["upgradePolicy"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("uid", flattenGkeonpremVmwareClusterUid(res["uid"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("state", flattenGkeonpremVmwareClusterState(res["state"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("endpoint", flattenGkeonpremVmwareClusterEndpoint(res["endpoint"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("reconciling", flattenGkeonpremVmwareClusterReconciling(res["reconciling"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("create_time", flattenGkeonpremVmwareClusterCreateTime(res["createTime"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("update_time", flattenGkeonpremVmwareClusterUpdateTime(res["updateTime"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("delete_time", flattenGkeonpremVmwareClusterDeleteTime(res["deleteTime"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("local_name", flattenGkeonpremVmwareClusterLocalName(res["localName"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("etag", flattenGkeonpremVmwareClusterEtag(res["etag"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("fleet", flattenGkeonpremVmwareClusterFleet(res["fleet"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("vcenter", flattenGkeonpremVmwareClusterVcenter(res["vcenter"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("status", flattenGkeonpremVmwareClusterStatus(res["status"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + if err := d.Set("effective_annotations", flattenGkeonpremVmwareClusterEffectiveAnnotations(res["annotations"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareCluster: %s", err) + } + + return nil +} + +func resourceGkeonpremVmwareClusterUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for VmwareCluster: %s", err) + } + billingProject = project + + obj := make(map[string]interface{}) + descriptionProp, err := expandGkeonpremVmwareClusterDescription(d.Get("description"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + onPremVersionProp, err := expandGkeonpremVmwareClusterOnPremVersion(d.Get("on_prem_version"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("on_prem_version"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, onPremVersionProp)) { + obj["onPremVersion"] = onPremVersionProp + } + controlPlaneNodeProp, err := expandGkeonpremVmwareClusterControlPlaneNode(d.Get("control_plane_node"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("control_plane_node"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, controlPlaneNodeProp)) { + obj["controlPlaneNode"] = controlPlaneNodeProp + } + antiAffinityGroupsProp, err := expandGkeonpremVmwareClusterAntiAffinityGroups(d.Get("anti_affinity_groups"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("anti_affinity_groups"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, antiAffinityGroupsProp)) { + obj["antiAffinityGroups"] = antiAffinityGroupsProp + } + storageProp, err := expandGkeonpremVmwareClusterStorage(d.Get("storage"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("storage"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, storageProp)) { + obj["storage"] = storageProp + } + networkConfigProp, err := expandGkeonpremVmwareClusterNetworkConfig(d.Get("network_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("network_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, networkConfigProp)) { + obj["networkConfig"] = networkConfigProp + } + loadBalancerProp, err := expandGkeonpremVmwareClusterLoadBalancer(d.Get("load_balancer"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("load_balancer"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, loadBalancerProp)) { + obj["loadBalancer"] = loadBalancerProp + } + dataplaneV2Prop, err := expandGkeonpremVmwareClusterDataplaneV2(d.Get("dataplane_v2"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("dataplane_v2"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, dataplaneV2Prop)) { + obj["dataplaneV2"] = dataplaneV2Prop + } + vmTrackingEnabledProp, err := expandGkeonpremVmwareClusterVmTrackingEnabled(d.Get("vm_tracking_enabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("vm_tracking_enabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, vmTrackingEnabledProp)) { + obj["vmTrackingEnabled"] = vmTrackingEnabledProp + } + autoRepairConfigProp, err := expandGkeonpremVmwareClusterAutoRepairConfig(d.Get("auto_repair_config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("auto_repair_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, autoRepairConfigProp)) { + obj["autoRepairConfig"] = autoRepairConfigProp + } + authorizationProp, err := expandGkeonpremVmwareClusterAuthorization(d.Get("authorization"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("authorization"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, authorizationProp)) { + obj["authorization"] = authorizationProp + } + enableControlPlaneV2Prop, err := expandGkeonpremVmwareClusterEnableControlPlaneV2(d.Get("enable_control_plane_v2"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enable_control_plane_v2"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enableControlPlaneV2Prop)) { + obj["enableControlPlaneV2"] = enableControlPlaneV2Prop + } + upgradePolicyProp, err := expandGkeonpremVmwareClusterUpgradePolicy(d.Get("upgrade_policy"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("upgrade_policy"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, upgradePolicyProp)) { + obj["upgradePolicy"] = upgradePolicyProp + } + vcenterProp, err := expandGkeonpremVmwareClusterVcenter(d.Get("vcenter"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("vcenter"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, vcenterProp)) { + obj["vcenter"] = vcenterProp + } + annotationsProp, err := expandGkeonpremVmwareClusterEffectiveAnnotations(d.Get("effective_annotations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_annotations"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, annotationsProp)) { + obj["annotations"] = annotationsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/vmwareClusters/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating VmwareCluster %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("description") { + updateMask = append(updateMask, "description") + } + + if d.HasChange("on_prem_version") { + updateMask = append(updateMask, "onPremVersion") + } + + if d.HasChange("control_plane_node") { + updateMask = append(updateMask, "controlPlaneNode") + } + + if d.HasChange("anti_affinity_groups") { + updateMask = append(updateMask, "antiAffinityGroups") + } + + if d.HasChange("storage") { + updateMask = append(updateMask, "storage") + } + + if d.HasChange("network_config") { + updateMask = append(updateMask, "networkConfig") + } + + if d.HasChange("load_balancer") { + updateMask = append(updateMask, "loadBalancer") + } + + if d.HasChange("dataplane_v2") { + updateMask = append(updateMask, "dataplaneV2") + } + + if d.HasChange("vm_tracking_enabled") { + updateMask = append(updateMask, "vmTrackingEnabled") + } + + if d.HasChange("auto_repair_config") { + updateMask = append(updateMask, "autoRepairConfig") + } + + if d.HasChange("authorization") { + updateMask = append(updateMask, "authorization") + } + + if d.HasChange("enable_control_plane_v2") { + updateMask = append(updateMask, "enableControlPlaneV2") + } + + if d.HasChange("upgrade_policy") { + updateMask = append(updateMask, "upgradePolicy") + } + + if d.HasChange("vcenter") { + updateMask = append(updateMask, "vcenter") + } + + if d.HasChange("effective_annotations") { + updateMask = append(updateMask, "annotations") + } + // updateMask is a URL parameter but not present in the schema, so ReplaceVars + // won't set it + url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + // if updateMask is empty we are not updating anything so skip the post + if len(updateMask) > 0 { + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "PATCH", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutUpdate), + }) + + if err != nil { + return fmt.Errorf("Error updating VmwareCluster %q: %s", d.Id(), err) + } else { + log.Printf("[DEBUG] Finished updating VmwareCluster %q: %#v", d.Id(), res) + } + + err = GkeonpremOperationWaitTime( + config, res, project, "Updating VmwareCluster", userAgent, + d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return err + } + } + + return resourceGkeonpremVmwareClusterRead(d, meta) +} + +func resourceGkeonpremVmwareClusterDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for VmwareCluster: %s", err) + } + billingProject = project + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/vmwareClusters/{{name}}?force=true") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting VmwareCluster %q", d.Id()) + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutDelete), + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, "VmwareCluster") + } + + err = GkeonpremOperationWaitTime( + config, res, project, "Deleting VmwareCluster", userAgent, + d.Timeout(schema.TimeoutDelete)) + + if err != nil { + return err + } + + log.Printf("[DEBUG] Finished deleting VmwareCluster %q: %#v", d.Id(), res) + return nil +} + +func resourceGkeonpremVmwareClusterImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*transport_tpg.Config) + if err := tpgresource.ParseImportId([]string{ + "^projects/(?P[^/]+)/locations/(?P[^/]+)/vmwareClusters/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)$", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/vmwareClusters/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenGkeonpremVmwareClusterAdminClusterMembership(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterOnPremVersion(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("annotations"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenGkeonpremVmwareClusterControlPlaneNode(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["cpus"] = + flattenGkeonpremVmwareClusterControlPlaneNodeCpus(original["cpus"], d, config) + transformed["memory"] = + flattenGkeonpremVmwareClusterControlPlaneNodeMemory(original["memory"], d, config) + transformed["replicas"] = + flattenGkeonpremVmwareClusterControlPlaneNodeReplicas(original["replicas"], d, config) + transformed["auto_resize_config"] = + flattenGkeonpremVmwareClusterControlPlaneNodeAutoResizeConfig(original["autoResizeConfig"], d, config) + transformed["vsphere_config"] = + flattenGkeonpremVmwareClusterControlPlaneNodeVsphereConfig(original["vsphereConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterControlPlaneNodeCpus(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 flattenGkeonpremVmwareClusterControlPlaneNodeMemory(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 flattenGkeonpremVmwareClusterControlPlaneNodeReplicas(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 flattenGkeonpremVmwareClusterControlPlaneNodeAutoResizeConfig(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["enabled"] = + flattenGkeonpremVmwareClusterControlPlaneNodeAutoResizeConfigEnabled(original["enabled"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterControlPlaneNodeAutoResizeConfigEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterControlPlaneNodeVsphereConfig(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["datastore"] = + flattenGkeonpremVmwareClusterControlPlaneNodeVsphereConfigDatastore(original["datastore"], d, config) + transformed["storage_policy_name"] = + flattenGkeonpremVmwareClusterControlPlaneNodeVsphereConfigStoragePolicyName(original["storagePolicyName"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterControlPlaneNodeVsphereConfigDatastore(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterControlPlaneNodeVsphereConfigStoragePolicyName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterAntiAffinityGroups(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["aag_config_disabled"] = + flattenGkeonpremVmwareClusterAntiAffinityGroupsAagConfigDisabled(original["aagConfigDisabled"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterAntiAffinityGroupsAagConfigDisabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterStorage(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["vsphere_csi_disabled"] = + flattenGkeonpremVmwareClusterStorageVsphereCsiDisabled(original["vsphereCsiDisabled"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterStorageVsphereCsiDisabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfig(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["service_address_cidr_blocks"] = + flattenGkeonpremVmwareClusterNetworkConfigServiceAddressCidrBlocks(original["serviceAddressCidrBlocks"], d, config) + transformed["pod_address_cidr_blocks"] = + flattenGkeonpremVmwareClusterNetworkConfigPodAddressCidrBlocks(original["podAddressCidrBlocks"], d, config) + transformed["static_ip_config"] = + flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfig(original["staticIpConfig"], d, config) + transformed["dhcp_ip_config"] = + flattenGkeonpremVmwareClusterNetworkConfigDhcpIpConfig(original["dhcpIpConfig"], d, config) + transformed["vcenter_network"] = + flattenGkeonpremVmwareClusterNetworkConfigVcenterNetwork(original["vcenterNetwork"], d, config) + transformed["host_config"] = + flattenGkeonpremVmwareClusterNetworkConfigHostConfig(original["hostConfig"], d, config) + transformed["control_plane_v2_config"] = + flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2Config(original["controlPlaneV2Config"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterNetworkConfigServiceAddressCidrBlocks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigPodAddressCidrBlocks(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfig(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["ip_blocks"] = + flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocks(original["ipBlocks"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocks(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{}{ + "netmask": flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksNetmask(original["netmask"], d, config), + "gateway": flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksGateway(original["gateway"], d, config), + "ips": flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIps(original["ips"], d, config), + }) + } + return transformed +} +func flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksNetmask(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksGateway(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIps(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{}{ + "ip": flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIpsIp(original["ip"], d, config), + "hostname": flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIpsHostname(original["hostname"], d, config), + }) + } + return transformed +} +func flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIpsIp(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIpsHostname(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigDhcpIpConfig(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["enabled"] = + flattenGkeonpremVmwareClusterNetworkConfigDhcpIpConfigEnabled(original["enabled"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterNetworkConfigDhcpIpConfigEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigVcenterNetwork(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigHostConfig(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["dns_servers"] = + flattenGkeonpremVmwareClusterNetworkConfigHostConfigDnsServers(original["dnsServers"], d, config) + transformed["ntp_servers"] = + flattenGkeonpremVmwareClusterNetworkConfigHostConfigNtpServers(original["ntpServers"], d, config) + transformed["dns_search_domains"] = + flattenGkeonpremVmwareClusterNetworkConfigHostConfigDnsSearchDomains(original["dnsSearchDomains"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterNetworkConfigHostConfigDnsServers(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigHostConfigNtpServers(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigHostConfigDnsSearchDomains(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2Config(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["control_plane_ip_block"] = + flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlock(original["controlPlaneIpBlock"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlock(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["netmask"] = + flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockNetmask(original["netmask"], d, config) + transformed["gateway"] = + flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockGateway(original["gateway"], d, config) + transformed["ips"] = + flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIps(original["ips"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockNetmask(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockGateway(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIps(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{}{ + "ip": flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIpsIp(original["ip"], d, config), + "hostname": flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIpsHostname(original["hostname"], d, config), + }) + } + return transformed +} +func flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIpsIp(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIpsHostname(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterLoadBalancer(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["vip_config"] = + flattenGkeonpremVmwareClusterLoadBalancerVipConfig(original["vipConfig"], d, config) + transformed["f5_config"] = + flattenGkeonpremVmwareClusterLoadBalancerF5Config(original["f5Config"], d, config) + transformed["manual_lb_config"] = + flattenGkeonpremVmwareClusterLoadBalancerManualLbConfig(original["manualLbConfig"], d, config) + transformed["metal_lb_config"] = + flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfig(original["metalLbConfig"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterLoadBalancerVipConfig(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["control_plane_vip"] = + flattenGkeonpremVmwareClusterLoadBalancerVipConfigControlPlaneVip(original["controlPlaneVip"], d, config) + transformed["ingress_vip"] = + flattenGkeonpremVmwareClusterLoadBalancerVipConfigIngressVip(original["ingressVip"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterLoadBalancerVipConfigControlPlaneVip(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterLoadBalancerVipConfigIngressVip(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterLoadBalancerF5Config(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["address"] = + flattenGkeonpremVmwareClusterLoadBalancerF5ConfigAddress(original["address"], d, config) + transformed["partition"] = + flattenGkeonpremVmwareClusterLoadBalancerF5ConfigPartition(original["partition"], d, config) + transformed["snat_pool"] = + flattenGkeonpremVmwareClusterLoadBalancerF5ConfigSnatPool(original["snatPool"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterLoadBalancerF5ConfigAddress(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterLoadBalancerF5ConfigPartition(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterLoadBalancerF5ConfigSnatPool(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterLoadBalancerManualLbConfig(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["ingress_http_node_port"] = + flattenGkeonpremVmwareClusterLoadBalancerManualLbConfigIngressHttpNodePort(original["ingressHttpNodePort"], d, config) + transformed["ingress_https_node_port"] = + flattenGkeonpremVmwareClusterLoadBalancerManualLbConfigIngressHttpsNodePort(original["ingressHttpsNodePort"], d, config) + transformed["control_plane_node_port"] = + flattenGkeonpremVmwareClusterLoadBalancerManualLbConfigControlPlaneNodePort(original["controlPlaneNodePort"], d, config) + transformed["konnectivity_server_node_port"] = + flattenGkeonpremVmwareClusterLoadBalancerManualLbConfigKonnectivityServerNodePort(original["konnectivityServerNodePort"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterLoadBalancerManualLbConfigIngressHttpNodePort(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 flattenGkeonpremVmwareClusterLoadBalancerManualLbConfigIngressHttpsNodePort(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 flattenGkeonpremVmwareClusterLoadBalancerManualLbConfigControlPlaneNodePort(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 flattenGkeonpremVmwareClusterLoadBalancerManualLbConfigKonnectivityServerNodePort(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 flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfig(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["address_pools"] = + flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPools(original["addressPools"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPools(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{}{ + "pool": flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsPool(original["pool"], d, config), + "addresses": flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsAddresses(original["addresses"], d, config), + "avoid_buggy_ips": flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsAvoidBuggyIps(original["avoidBuggyIps"], d, config), + "manual_assign": flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsManualAssign(original["manualAssign"], d, config), + }) + } + return transformed +} +func flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsPool(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsAddresses(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsAvoidBuggyIps(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsManualAssign(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterDataplaneV2(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["dataplane_v2_enabled"] = + flattenGkeonpremVmwareClusterDataplaneV2DataplaneV2Enabled(original["dataplaneV2Enabled"], d, config) + transformed["windows_dataplane_v2_enabled"] = + flattenGkeonpremVmwareClusterDataplaneV2WindowsDataplaneV2Enabled(original["windowsDataplaneV2Enabled"], d, config) + transformed["advanced_networking"] = + flattenGkeonpremVmwareClusterDataplaneV2AdvancedNetworking(original["advancedNetworking"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterDataplaneV2DataplaneV2Enabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterDataplaneV2WindowsDataplaneV2Enabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterDataplaneV2AdvancedNetworking(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterVmTrackingEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterAutoRepairConfig(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["enabled"] = + flattenGkeonpremVmwareClusterAutoRepairConfigEnabled(original["enabled"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterAutoRepairConfigEnabled(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterAuthorization(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["admin_users"] = + flattenGkeonpremVmwareClusterAuthorizationAdminUsers(original["adminUsers"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterAuthorizationAdminUsers(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{}{ + "username": flattenGkeonpremVmwareClusterAuthorizationAdminUsersUsername(original["username"], d, config), + }) + } + return transformed +} +func flattenGkeonpremVmwareClusterAuthorizationAdminUsersUsername(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterValidationCheck(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["options"] = + flattenGkeonpremVmwareClusterValidationCheckOptions(original["options"], d, config) + transformed["status"] = + flattenGkeonpremVmwareClusterValidationCheckStatus(original["status"], d, config) + transformed["scenario"] = + flattenGkeonpremVmwareClusterValidationCheckScenario(original["scenario"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterValidationCheckOptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterValidationCheckStatus(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["result"] = + flattenGkeonpremVmwareClusterValidationCheckStatusResult(original["result"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterValidationCheckStatusResult(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{}{ + "options": flattenGkeonpremVmwareClusterValidationCheckStatusResultOptions(original["options"], d, config), + "description": flattenGkeonpremVmwareClusterValidationCheckStatusResultDescription(original["description"], d, config), + "category": flattenGkeonpremVmwareClusterValidationCheckStatusResultCategory(original["category"], d, config), + "reason": flattenGkeonpremVmwareClusterValidationCheckStatusResultReason(original["reason"], d, config), + "details": flattenGkeonpremVmwareClusterValidationCheckStatusResultDetails(original["details"], d, config), + }) + } + return transformed +} +func flattenGkeonpremVmwareClusterValidationCheckStatusResultOptions(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterValidationCheckStatusResultDescription(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterValidationCheckStatusResultCategory(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterValidationCheckStatusResultReason(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterValidationCheckStatusResultDetails(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterValidationCheckScenario(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterEnableControlPlaneV2(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterUpgradePolicy(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["control_plane_only"] = + flattenGkeonpremVmwareClusterUpgradePolicyControlPlaneOnly(original["controlPlaneOnly"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterUpgradePolicyControlPlaneOnly(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterUid(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterEndpoint(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterReconciling(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterUpdateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterDeleteTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterLocalName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterEtag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterFleet(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["membership"] = + flattenGkeonpremVmwareClusterFleetMembership(original["membership"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterFleetMembership(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterVcenter(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["resource_pool"] = + flattenGkeonpremVmwareClusterVcenterResourcePool(original["resourcePool"], d, config) + transformed["datastore"] = + flattenGkeonpremVmwareClusterVcenterDatastore(original["datastore"], d, config) + transformed["datacenter"] = + flattenGkeonpremVmwareClusterVcenterDatacenter(original["datacenter"], d, config) + transformed["cluster"] = + flattenGkeonpremVmwareClusterVcenterCluster(original["cluster"], d, config) + transformed["folder"] = + flattenGkeonpremVmwareClusterVcenterFolder(original["folder"], d, config) + transformed["ca_cert_data"] = + flattenGkeonpremVmwareClusterVcenterCaCertData(original["caCertData"], d, config) + transformed["address"] = + flattenGkeonpremVmwareClusterVcenterAddress(original["address"], d, config) + transformed["storage_policy_name"] = + flattenGkeonpremVmwareClusterVcenterStoragePolicyName(original["storagePolicyName"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterVcenterResourcePool(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterVcenterDatastore(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterVcenterDatacenter(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterVcenterCluster(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterVcenterFolder(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterVcenterCaCertData(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterVcenterAddress(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterVcenterStoragePolicyName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterStatus(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["error_message"] = + flattenGkeonpremVmwareClusterStatusErrorMessage(original["errorMessage"], d, config) + transformed["conditions"] = + flattenGkeonpremVmwareClusterStatusConditions(original["conditions"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareClusterStatusErrorMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterStatusConditions(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{}{ + "type": flattenGkeonpremVmwareClusterStatusConditionsType(original["type"], d, config), + "reason": flattenGkeonpremVmwareClusterStatusConditionsReason(original["reason"], d, config), + "message": flattenGkeonpremVmwareClusterStatusConditionsMessage(original["message"], d, config), + "last_transition_time": flattenGkeonpremVmwareClusterStatusConditionsLastTransitionTime(original["lastTransitionTime"], d, config), + "state": flattenGkeonpremVmwareClusterStatusConditionsState(original["state"], d, config), + }) + } + return transformed +} +func flattenGkeonpremVmwareClusterStatusConditionsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterStatusConditionsReason(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterStatusConditionsMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterStatusConditionsLastTransitionTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterStatusConditionsState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareClusterEffectiveAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandGkeonpremVmwareClusterAdminClusterMembership(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterOnPremVersion(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterControlPlaneNode(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{}) + + transformedCpus, err := expandGkeonpremVmwareClusterControlPlaneNodeCpus(original["cpus"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCpus); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["cpus"] = transformedCpus + } + + transformedMemory, err := expandGkeonpremVmwareClusterControlPlaneNodeMemory(original["memory"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMemory); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["memory"] = transformedMemory + } + + transformedReplicas, err := expandGkeonpremVmwareClusterControlPlaneNodeReplicas(original["replicas"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedReplicas); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["replicas"] = transformedReplicas + } + + transformedAutoResizeConfig, err := expandGkeonpremVmwareClusterControlPlaneNodeAutoResizeConfig(original["auto_resize_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAutoResizeConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["autoResizeConfig"] = transformedAutoResizeConfig + } + + transformedVsphereConfig, err := expandGkeonpremVmwareClusterControlPlaneNodeVsphereConfig(original["vsphere_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVsphereConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vsphereConfig"] = transformedVsphereConfig + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterControlPlaneNodeCpus(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterControlPlaneNodeMemory(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterControlPlaneNodeReplicas(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterControlPlaneNodeAutoResizeConfig(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{}) + + transformedEnabled, err := expandGkeonpremVmwareClusterControlPlaneNodeAutoResizeConfigEnabled(original["enabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["enabled"] = transformedEnabled + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterControlPlaneNodeAutoResizeConfigEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterControlPlaneNodeVsphereConfig(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{}) + + transformedDatastore, err := expandGkeonpremVmwareClusterControlPlaneNodeVsphereConfigDatastore(original["datastore"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDatastore); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["datastore"] = transformedDatastore + } + + transformedStoragePolicyName, err := expandGkeonpremVmwareClusterControlPlaneNodeVsphereConfigStoragePolicyName(original["storage_policy_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStoragePolicyName); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["storagePolicyName"] = transformedStoragePolicyName + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterControlPlaneNodeVsphereConfigDatastore(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterControlPlaneNodeVsphereConfigStoragePolicyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterAntiAffinityGroups(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{}) + + transformedAagConfigDisabled, err := expandGkeonpremVmwareClusterAntiAffinityGroupsAagConfigDisabled(original["aag_config_disabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAagConfigDisabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["aagConfigDisabled"] = transformedAagConfigDisabled + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterAntiAffinityGroupsAagConfigDisabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterStorage(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{}) + + transformedVsphereCsiDisabled, err := expandGkeonpremVmwareClusterStorageVsphereCsiDisabled(original["vsphere_csi_disabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVsphereCsiDisabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vsphereCsiDisabled"] = transformedVsphereCsiDisabled + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterStorageVsphereCsiDisabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfig(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{}) + + transformedServiceAddressCidrBlocks, err := expandGkeonpremVmwareClusterNetworkConfigServiceAddressCidrBlocks(original["service_address_cidr_blocks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedServiceAddressCidrBlocks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["serviceAddressCidrBlocks"] = transformedServiceAddressCidrBlocks + } + + transformedPodAddressCidrBlocks, err := expandGkeonpremVmwareClusterNetworkConfigPodAddressCidrBlocks(original["pod_address_cidr_blocks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPodAddressCidrBlocks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["podAddressCidrBlocks"] = transformedPodAddressCidrBlocks + } + + transformedStaticIpConfig, err := expandGkeonpremVmwareClusterNetworkConfigStaticIpConfig(original["static_ip_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStaticIpConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["staticIpConfig"] = transformedStaticIpConfig + } + + transformedDhcpIpConfig, err := expandGkeonpremVmwareClusterNetworkConfigDhcpIpConfig(original["dhcp_ip_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDhcpIpConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["dhcpIpConfig"] = transformedDhcpIpConfig + } + + transformedVcenterNetwork, err := expandGkeonpremVmwareClusterNetworkConfigVcenterNetwork(original["vcenter_network"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVcenterNetwork); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vcenterNetwork"] = transformedVcenterNetwork + } + + transformedHostConfig, err := expandGkeonpremVmwareClusterNetworkConfigHostConfig(original["host_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedHostConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["hostConfig"] = transformedHostConfig + } + + transformedControlPlaneV2Config, err := expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2Config(original["control_plane_v2_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneV2Config); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneV2Config"] = transformedControlPlaneV2Config + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigServiceAddressCidrBlocks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigPodAddressCidrBlocks(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigStaticIpConfig(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{}) + + transformedIpBlocks, err := expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocks(original["ip_blocks"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIpBlocks); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ipBlocks"] = transformedIpBlocks + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocks(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{}) + + transformedNetmask, err := expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksNetmask(original["netmask"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNetmask); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["netmask"] = transformedNetmask + } + + transformedGateway, err := expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksGateway(original["gateway"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedGateway); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["gateway"] = transformedGateway + } + + transformedIps, err := expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIps(original["ips"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIps); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ips"] = transformedIps + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksNetmask(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksGateway(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIps(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{}) + + transformedIp, err := expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIpsIp(original["ip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIp); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ip"] = transformedIp + } + + transformedHostname, err := expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIpsHostname(original["hostname"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedHostname); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["hostname"] = transformedHostname + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIpsIp(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigStaticIpConfigIpBlocksIpsHostname(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigDhcpIpConfig(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{}) + + transformedEnabled, err := expandGkeonpremVmwareClusterNetworkConfigDhcpIpConfigEnabled(original["enabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["enabled"] = transformedEnabled + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigDhcpIpConfigEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigVcenterNetwork(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigHostConfig(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{}) + + transformedDnsServers, err := expandGkeonpremVmwareClusterNetworkConfigHostConfigDnsServers(original["dns_servers"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDnsServers); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["dnsServers"] = transformedDnsServers + } + + transformedNtpServers, err := expandGkeonpremVmwareClusterNetworkConfigHostConfigNtpServers(original["ntp_servers"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNtpServers); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ntpServers"] = transformedNtpServers + } + + transformedDnsSearchDomains, err := expandGkeonpremVmwareClusterNetworkConfigHostConfigDnsSearchDomains(original["dns_search_domains"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDnsSearchDomains); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["dnsSearchDomains"] = transformedDnsSearchDomains + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigHostConfigDnsServers(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigHostConfigNtpServers(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigHostConfigDnsSearchDomains(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2Config(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{}) + + transformedControlPlaneIpBlock, err := expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlock(original["control_plane_ip_block"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneIpBlock); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneIpBlock"] = transformedControlPlaneIpBlock + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlock(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{}) + + transformedNetmask, err := expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockNetmask(original["netmask"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedNetmask); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["netmask"] = transformedNetmask + } + + transformedGateway, err := expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockGateway(original["gateway"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedGateway); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["gateway"] = transformedGateway + } + + transformedIps, err := expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIps(original["ips"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIps); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ips"] = transformedIps + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockNetmask(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockGateway(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIps(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{}) + + transformedIp, err := expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIpsIp(original["ip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIp); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ip"] = transformedIp + } + + transformedHostname, err := expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIpsHostname(original["hostname"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedHostname); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["hostname"] = transformedHostname + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIpsIp(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterNetworkConfigControlPlaneV2ConfigControlPlaneIpBlockIpsHostname(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancer(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{}) + + transformedVipConfig, err := expandGkeonpremVmwareClusterLoadBalancerVipConfig(original["vip_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVipConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vipConfig"] = transformedVipConfig + } + + transformedF5Config, err := expandGkeonpremVmwareClusterLoadBalancerF5Config(original["f5_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedF5Config); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["f5Config"] = transformedF5Config + } + + transformedManualLbConfig, err := expandGkeonpremVmwareClusterLoadBalancerManualLbConfig(original["manual_lb_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedManualLbConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["manualLbConfig"] = transformedManualLbConfig + } + + transformedMetalLbConfig, err := expandGkeonpremVmwareClusterLoadBalancerMetalLbConfig(original["metal_lb_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMetalLbConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["metalLbConfig"] = transformedMetalLbConfig + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerVipConfig(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{}) + + transformedControlPlaneVip, err := expandGkeonpremVmwareClusterLoadBalancerVipConfigControlPlaneVip(original["control_plane_vip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneVip); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneVip"] = transformedControlPlaneVip + } + + transformedIngressVip, err := expandGkeonpremVmwareClusterLoadBalancerVipConfigIngressVip(original["ingress_vip"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIngressVip); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ingressVip"] = transformedIngressVip + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerVipConfigControlPlaneVip(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerVipConfigIngressVip(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerF5Config(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{}) + + transformedAddress, err := expandGkeonpremVmwareClusterLoadBalancerF5ConfigAddress(original["address"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAddress); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["address"] = transformedAddress + } + + transformedPartition, err := expandGkeonpremVmwareClusterLoadBalancerF5ConfigPartition(original["partition"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPartition); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["partition"] = transformedPartition + } + + transformedSnatPool, err := expandGkeonpremVmwareClusterLoadBalancerF5ConfigSnatPool(original["snat_pool"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSnatPool); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["snatPool"] = transformedSnatPool + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerF5ConfigAddress(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerF5ConfigPartition(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerF5ConfigSnatPool(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerManualLbConfig(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{}) + + transformedIngressHttpNodePort, err := expandGkeonpremVmwareClusterLoadBalancerManualLbConfigIngressHttpNodePort(original["ingress_http_node_port"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIngressHttpNodePort); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ingressHttpNodePort"] = transformedIngressHttpNodePort + } + + transformedIngressHttpsNodePort, err := expandGkeonpremVmwareClusterLoadBalancerManualLbConfigIngressHttpsNodePort(original["ingress_https_node_port"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIngressHttpsNodePort); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["ingressHttpsNodePort"] = transformedIngressHttpsNodePort + } + + transformedControlPlaneNodePort, err := expandGkeonpremVmwareClusterLoadBalancerManualLbConfigControlPlaneNodePort(original["control_plane_node_port"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneNodePort); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneNodePort"] = transformedControlPlaneNodePort + } + + transformedKonnectivityServerNodePort, err := expandGkeonpremVmwareClusterLoadBalancerManualLbConfigKonnectivityServerNodePort(original["konnectivity_server_node_port"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKonnectivityServerNodePort); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["konnectivityServerNodePort"] = transformedKonnectivityServerNodePort + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerManualLbConfigIngressHttpNodePort(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerManualLbConfigIngressHttpsNodePort(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerManualLbConfigControlPlaneNodePort(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerManualLbConfigKonnectivityServerNodePort(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerMetalLbConfig(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{}) + + transformedAddressPools, err := expandGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPools(original["address_pools"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAddressPools); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["addressPools"] = transformedAddressPools + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPools(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{}) + + transformedPool, err := expandGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsPool(original["pool"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPool); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["pool"] = transformedPool + } + + transformedAddresses, err := expandGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsAddresses(original["addresses"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAddresses); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["addresses"] = transformedAddresses + } + + transformedAvoidBuggyIps, err := expandGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsAvoidBuggyIps(original["avoid_buggy_ips"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAvoidBuggyIps); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["avoidBuggyIps"] = transformedAvoidBuggyIps + } + + transformedManualAssign, err := expandGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsManualAssign(original["manual_assign"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedManualAssign); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["manualAssign"] = transformedManualAssign + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsPool(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsAddresses(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsAvoidBuggyIps(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterLoadBalancerMetalLbConfigAddressPoolsManualAssign(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterDataplaneV2(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{}) + + transformedDataplaneV2Enabled, err := expandGkeonpremVmwareClusterDataplaneV2DataplaneV2Enabled(original["dataplane_v2_enabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDataplaneV2Enabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["dataplaneV2Enabled"] = transformedDataplaneV2Enabled + } + + transformedWindowsDataplaneV2Enabled, err := expandGkeonpremVmwareClusterDataplaneV2WindowsDataplaneV2Enabled(original["windows_dataplane_v2_enabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedWindowsDataplaneV2Enabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["windowsDataplaneV2Enabled"] = transformedWindowsDataplaneV2Enabled + } + + transformedAdvancedNetworking, err := expandGkeonpremVmwareClusterDataplaneV2AdvancedNetworking(original["advanced_networking"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAdvancedNetworking); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["advancedNetworking"] = transformedAdvancedNetworking + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterDataplaneV2DataplaneV2Enabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterDataplaneV2WindowsDataplaneV2Enabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterDataplaneV2AdvancedNetworking(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterVmTrackingEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterAutoRepairConfig(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{}) + + transformedEnabled, err := expandGkeonpremVmwareClusterAutoRepairConfigEnabled(original["enabled"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnabled); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["enabled"] = transformedEnabled + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterAutoRepairConfigEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterAuthorization(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{}) + + transformedAdminUsers, err := expandGkeonpremVmwareClusterAuthorizationAdminUsers(original["admin_users"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAdminUsers); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["adminUsers"] = transformedAdminUsers + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterAuthorizationAdminUsers(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{}) + + transformedUsername, err := expandGkeonpremVmwareClusterAuthorizationAdminUsersUsername(original["username"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUsername); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["username"] = transformedUsername + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremVmwareClusterAuthorizationAdminUsersUsername(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterEnableControlPlaneV2(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterUpgradePolicy(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{}) + + transformedControlPlaneOnly, err := expandGkeonpremVmwareClusterUpgradePolicyControlPlaneOnly(original["control_plane_only"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedControlPlaneOnly); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["controlPlaneOnly"] = transformedControlPlaneOnly + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterUpgradePolicyControlPlaneOnly(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterVcenter(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{}) + + transformedResourcePool, err := expandGkeonpremVmwareClusterVcenterResourcePool(original["resource_pool"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedResourcePool); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["resourcePool"] = transformedResourcePool + } + + transformedDatastore, err := expandGkeonpremVmwareClusterVcenterDatastore(original["datastore"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDatastore); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["datastore"] = transformedDatastore + } + + transformedDatacenter, err := expandGkeonpremVmwareClusterVcenterDatacenter(original["datacenter"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDatacenter); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["datacenter"] = transformedDatacenter + } + + transformedCluster, err := expandGkeonpremVmwareClusterVcenterCluster(original["cluster"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCluster); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["cluster"] = transformedCluster + } + + transformedFolder, err := expandGkeonpremVmwareClusterVcenterFolder(original["folder"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFolder); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["folder"] = transformedFolder + } + + transformedCaCertData, err := expandGkeonpremVmwareClusterVcenterCaCertData(original["ca_cert_data"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCaCertData); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["caCertData"] = transformedCaCertData + } + + transformedAddress, err := expandGkeonpremVmwareClusterVcenterAddress(original["address"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAddress); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["address"] = transformedAddress + } + + transformedStoragePolicyName, err := expandGkeonpremVmwareClusterVcenterStoragePolicyName(original["storage_policy_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStoragePolicyName); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["storagePolicyName"] = transformedStoragePolicyName + } + + return transformed, nil +} + +func expandGkeonpremVmwareClusterVcenterResourcePool(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterVcenterDatastore(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterVcenterDatacenter(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterVcenterCluster(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterVcenterFolder(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterVcenterCaCertData(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterVcenterAddress(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterVcenterStoragePolicyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareClusterEffectiveAnnotations(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} diff --git a/google/services/gkeonprem/resource_gkeonprem_vmware_cluster_generated_test.go b/google/services/gkeonprem/resource_gkeonprem_vmware_cluster_generated_test.go new file mode 100644 index 00000000000..28d61275d0a --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_vmware_cluster_generated_test.go @@ -0,0 +1,355 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func TestAccGkeonpremVmwareCluster_gkeonpremVmwareClusterBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremVmwareClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremVmwareCluster_gkeonpremVmwareClusterBasicExample(context), + }, + { + ResourceName: "google_gkeonprem_vmware_cluster.cluster-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremVmwareCluster_gkeonpremVmwareClusterBasicExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_vmware_cluster" "cluster-basic" { + name = "tf-test-cluster-basic%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + annotations = {} + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + dhcp_ip_config { + enabled = true + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + metal_lb_config { + address_pools { + pool = "ingress-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + avoid_buggy_ips = true + } + address_pools { + pool = "lb-test-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + avoid_buggy_ips = true + } + } + } +} +`, context) +} + +func TestAccGkeonpremVmwareCluster_gkeonpremVmwareClusterF5lbExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremVmwareClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremVmwareCluster_gkeonpremVmwareClusterF5lbExample(context), + }, + { + ResourceName: "google_gkeonprem_vmware_cluster.cluster-f5lb", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremVmwareCluster_gkeonpremVmwareClusterF5lbExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_vmware_cluster" "cluster-f5lb" { + name = "tf-test-cluster-f5lb%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + annotations = {} + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + dhcp_ip_config { + enabled = true + } + control_plane_v2_config { + control_plane_ip_block { + ips { + hostname = "test-hostname" + ip = "10.0.0.1" + } + netmask="10.0.0.1/32" + gateway="test-gateway" + } + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + auto_resize_config { + enabled = true + } + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + f5_config { + address = "10.0.0.1" + partition = "test-partition" + snat_pool = "test-snap-pool" + } + } + dataplane_v2 { + dataplane_v2_enabled = true + windows_dataplane_v2_enabled = true + advanced_networking = true + } + vm_tracking_enabled = true + enable_control_plane_v2 = true + authorization { + admin_users { + username = "testuser@gmail.com" + } + } + anti_affinity_groups { + aag_config_disabled = true + } + auto_repair_config { + enabled = true + } + storage { + vsphere_csi_disabled = true + } +} +`, context) +} + +func TestAccGkeonpremVmwareCluster_gkeonpremVmwareClusterManuallbExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremVmwareClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremVmwareCluster_gkeonpremVmwareClusterManuallbExample(context), + }, + { + ResourceName: "google_gkeonprem_vmware_cluster.cluster-manuallb", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremVmwareCluster_gkeonpremVmwareClusterManuallbExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_vmware_cluster" "cluster-manuallb" { + name = "tf-test-cluster-manuallb%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + annotations = {} + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + host_config { + dns_servers = ["10.254.41.1"] + ntp_servers = ["216.239.35.8"] + dns_search_domains = ["test-domain"] + } + + static_ip_config { + ip_blocks { + netmask = "255.255.252.0" + gateway = "10.251.31.254" + ips { + ip = "10.251.30.153" + hostname = "test-hostname1" + } + ips { + ip = "10.251.31.206" + hostname = "test-hostname2" + } + ips { + ip = "10.251.31.193" + hostname = "test-hostname3" + } + ips { + ip = "10.251.30.230" + hostname = "test-hostname4" + } + } + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + auto_resize_config { + enabled = true + } + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + manual_lb_config { + ingress_http_node_port = 30005 + ingress_https_node_port = 30006 + control_plane_node_port = 30007 + konnectivity_server_node_port = 30008 + } + } + vcenter { + resource_pool = "test-resource-pool" + datastore = "test-datastore" + datacenter = "test-datacenter" + cluster = "test-cluster" + folder = "test-folder" + ca_cert_data = "test-ca-cert-data" + storage_policy_name = "test-storage-policy-name" + } + dataplane_v2 { + dataplane_v2_enabled = true + windows_dataplane_v2_enabled = true + advanced_networking = true + } + vm_tracking_enabled = true + enable_control_plane_v2 = true + upgrade_policy { + control_plane_only = true + } + authorization { + admin_users { + username = "testuser@gmail.com" + } + } + anti_affinity_groups { + aag_config_disabled = true + } + auto_repair_config { + enabled = true + } +} +`, context) +} + +func testAccCheckGkeonpremVmwareClusterDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_gkeonprem_vmware_cluster" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/vmwareClusters/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("GkeonpremVmwareCluster still exists at %s", url) + } + } + + return nil + } +} diff --git a/google/services/gkeonprem/resource_gkeonprem_vmware_cluster_sweeper.go b/google/services/gkeonprem/resource_gkeonprem_vmware_cluster_sweeper.go new file mode 100644 index 00000000000..9e3318b1b50 --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_vmware_cluster_sweeper.go @@ -0,0 +1,139 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem + +import ( + "context" + "log" + "strings" + "testing" + + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/sweeper" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func init() { + sweeper.AddTestSweepers("GkeonpremVmwareCluster", testSweepGkeonpremVmwareCluster) +} + +// At the time of writing, the CI only passes us-central1 as the region +func testSweepGkeonpremVmwareCluster(region string) error { + resourceName := "GkeonpremVmwareCluster" + log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) + + config, err := sweeper.SharedConfigForRegion(region) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) + return err + } + + err = config.LoadAndValidate(context.Background()) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) + return err + } + + t := &testing.T{} + billingId := envvar.GetTestBillingAccountFromEnv(t) + + // Setup variables to replace in list template + d := &tpgresource.ResourceDataMock{ + FieldsInSchema: map[string]interface{}{ + "project": config.Project, + "region": region, + "location": region, + "zone": "-", + "billing_account": billingId, + }, + } + + listTemplate := strings.Split("https://gkeonprem.googleapis.com/v1/projects/{{project}}/locations/{{location}}/vmwareClusters", "?")[0] + listUrl, err := tpgresource.ReplaceVars(d, config, listTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) + return nil + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: config.Project, + RawURL: listUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) + return nil + } + + resourceList, ok := res["vmwareClusters"] + if !ok { + log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") + return nil + } + + rl := resourceList.([]interface{}) + + log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) + // Keep count of items that aren't sweepable for logging. + nonPrefixCount := 0 + for _, ri := range rl { + obj := ri.(map[string]interface{}) + if obj["name"] == nil { + log.Printf("[INFO][SWEEPER_LOG] %s resource name was nil", resourceName) + return nil + } + + name := tpgresource.GetResourceNameFromSelfLink(obj["name"].(string)) + // Skip resources that shouldn't be sweeped + if !sweeper.IsSweepableTestResource(name) { + nonPrefixCount++ + continue + } + + deleteTemplate := "https://gkeonprem.googleapis.com/v1/projects/{{project}}/locations/{{location}}/vmwareClusters/{{name}}?force=true" + deleteUrl, err := tpgresource.ReplaceVars(d, config, deleteTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) + return nil + } + deleteUrl = deleteUrl + name + + // Don't wait on operations as we may have a lot to delete + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: config.Project, + RawURL: deleteUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) + } else { + log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) + } + } + + if nonPrefixCount > 0 { + log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) + } + + return nil +} diff --git a/google/services/gkeonprem/resource_gkeonprem_vmware_cluster_test.go b/google/services/gkeonprem/resource_gkeonprem_vmware_cluster_test.go index 0ad9b6a9bdd..32609747778 100644 --- a/google/services/gkeonprem/resource_gkeonprem_vmware_cluster_test.go +++ b/google/services/gkeonprem/resource_gkeonprem_vmware_cluster_test.go @@ -1,3 +1,484 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package gkeonprem_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccGkeonpremVmwareCluster_vmwareClusterUpdateBasic(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremVmwareClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremVmwareCluster_vmwareClusterUpdateMetalLbStart(context), + }, + { + ResourceName: "google_gkeonprem_vmware_cluster.cluster", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, + }, + { + Config: testAccGkeonpremVmwareCluster_vmwareClusterUpdateMetalLb(context), + }, + { + ResourceName: "google_gkeonprem_vmware_cluster.cluster", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, + }, + }, + }) +} + +func TestAccGkeonpremVmwareCluster_vmwareClusterUpdateF5Lb(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremVmwareClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremVmwareCluster_vmwareClusterUpdateF5LbStart(context), + }, + { + ResourceName: "google_gkeonprem_vmware_cluster.cluster", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGkeonpremVmwareCluster_vmwareClusterUpdateF5lb(context), + }, + { + ResourceName: "google_gkeonprem_vmware_cluster.cluster", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGkeonpremVmwareCluster_vmwareClusterUpdateManualLb(t *testing.T) { + // VCR fails to handle batched project services + acctest.SkipIfVcr(t) + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremVmwareClusterDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremVmwareCluster_vmwareClusterUpdateManualLbStart(context), + }, + { + ResourceName: "google_gkeonprem_vmware_cluster.cluster", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGkeonpremVmwareCluster_vmwareClusterUpdateManualLb(context), + }, + { + ResourceName: "google_gkeonprem_vmware_cluster.cluster", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccGkeonpremVmwareCluster_vmwareClusterUpdateMetalLbStart(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_vmware_cluster" "cluster" { + name = "tf-test-cluster-%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + annotations = { + env = "test" + } + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + dhcp_ip_config { + enabled = true + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + metal_lb_config { + address_pools { + pool = "ingress-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + avoid_buggy_ips = true + } + address_pools { + pool = "lb-test-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + avoid_buggy_ips = true + } + } + } + } +`, context) +} + +func testAccGkeonpremVmwareCluster_vmwareClusterUpdateMetalLb(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_vmware_cluster" "cluster" { + name = "tf-test-cluster-%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster updated" + on_prem_version = "1.13.1-gke.36" + annotations = { + env = "test-update" + } + network_config { + service_address_cidr_blocks = ["10.96.0.0/16"] + pod_address_cidr_blocks = ["192.168.0.0/20"] + dhcp_ip_config { + enabled = true + } + } + control_plane_node { + cpus = 5 + memory = 4098 + replicas = 3 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.6" + ingress_vip = "10.251.135.20" + } + metal_lb_config { + address_pools { + pool = "ingress-ip-updated" + manual_assign = "false" + addresses = ["10.251.135.20"] + avoid_buggy_ips = false + } + address_pools { + pool = "lb-test-ip-updated" + manual_assign = "false" + addresses = ["10.251.135.20"] + avoid_buggy_ips = false + } + } + } + } +`, context) +} + +func testAccGkeonpremVmwareCluster_vmwareClusterUpdateF5LbStart(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_vmware_cluster" "cluster" { + name = "tf-test-cluster-%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + annotations = {} + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + dhcp_ip_config { + enabled = true + } + control_plane_v2_config { + control_plane_ip_block { + ips { + hostname = "test-hostname" + ip = "10.0.0.1" + } + netmask="10.0.0.1/32" + gateway="test-gateway" + } + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + f5_config { + address = "10.0.0.1" + partition = "test-partition" + snat_pool = "test-snap-pool" + } + } + } +`, context) +} + +func testAccGkeonpremVmwareCluster_vmwareClusterUpdateF5lb(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_vmware_cluster" "cluster" { + name = "tf-test-cluster-%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + annotations = {} + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + dhcp_ip_config { + enabled = true + } + control_plane_v2_config { + control_plane_ip_block { + ips { + hostname = "test-hostname-updated" + ip = "10.0.0.2" + } + netmask="10.0.0.2/32" + gateway="test-gateway-updated" + } + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + f5_config { + address = "10.0.0.2" + partition = "test-partition-updated" + snat_pool = "test-snap-pool-updated" + } + } + } +`, context) +} + +func testAccGkeonpremVmwareCluster_vmwareClusterUpdateManualLbStart(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_vmware_cluster" "cluster" { + name = "tf-test-cluster-%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + annotations = {} + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + host_config { + dns_servers = ["10.254.41.1"] + ntp_servers = ["216.239.35.8"] + dns_search_domains = ["test-domain"] + } + static_ip_config { + ip_blocks { + netmask = "255.255.252.0" + gateway = "10.251.31.254" + ips { + ip = "10.251.30.153" + hostname = "test-hostname1" + } + ips { + ip = "10.251.31.206" + hostname = "test-hostname2" + } + ips { + ip = "10.251.31.193" + hostname = "test-hostname3" + } + ips { + ip = "10.251.30.230" + hostname = "test-hostname4" + } + } + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + manual_lb_config { + ingress_http_node_port = 30005 + ingress_https_node_port = 30006 + control_plane_node_port = 30007 + konnectivity_server_node_port = 30008 + } + } + vcenter { + resource_pool = "test-resource-pool" + datastore = "test-datastore" + datacenter = "test-datacenter" + cluster = "test-cluster" + folder = "test-folder" + ca_cert_data = "test-ca-cert-data" + storage_policy_name = "test-storage-policy-name" + } + dataplane_v2 { + dataplane_v2_enabled = true + windows_dataplane_v2_enabled = true + advanced_networking = true + } + vm_tracking_enabled = true + enable_control_plane_v2 = true + upgrade_policy { + control_plane_only = true + } + authorization { + admin_users { + username = "testuser@gmail.com" + } + } + anti_affinity_groups { + aag_config_disabled = true + } + auto_repair_config { + enabled = true + } + } +`, context) +} + +func testAccGkeonpremVmwareCluster_vmwareClusterUpdateManualLb(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_vmware_cluster" "cluster" { + name = "tf-test-cluster-%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + annotations = {} + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + host_config { + dns_servers = ["10.254.41.1"] + ntp_servers = ["216.239.35.8"] + dns_search_domains = ["test-domain"] + } + static_ip_config { + ip_blocks { + netmask = "255.255.252.1" + gateway = "10.251.31.255" + ips { + ip = "10.251.30.154" + hostname = "test-hostname1-updated" + } + ips { + ip = "10.251.31.206" + hostname = "test-hostname2" + } + ips { + ip = "10.251.31.193" + hostname = "test-hostname3" + } + ips { + ip = "10.251.30.230" + hostname = "test-hostname4" + } + } + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + manual_lb_config { + ingress_http_node_port = 30006 + ingress_https_node_port = 30007 + control_plane_node_port = 30008 + konnectivity_server_node_port = 30009 + } + } + vcenter { + resource_pool = "test-resource-pool-updated" + datastore = "test-datastore-updated" + datacenter = "test-datacenter-updated" + cluster = "test-cluster-updated" + folder = "test-folder-updated" + ca_cert_data = "test-ca-cert-data-updated" + storage_policy_name = "test-storage-policy-name-updated" + } + dataplane_v2 { + dataplane_v2_enabled = true + windows_dataplane_v2_enabled = true + advanced_networking = true + } + vm_tracking_enabled = false + enable_control_plane_v2 = false + upgrade_policy { + control_plane_only = true + } + authorization { + admin_users { + username = "testuser-updated@gmail.com" + } + } + anti_affinity_groups { + aag_config_disabled = true + } + auto_repair_config { + enabled = true + } + } +`, context) +} diff --git a/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool.go b/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool.go new file mode 100644 index 00000000000..60558f2c940 --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool.go @@ -0,0 +1,1352 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-provider-google/google/verify" +) + +func ResourceGkeonpremVmwareNodePool() *schema.Resource { + return &schema.Resource{ + Create: resourceGkeonpremVmwareNodePoolCreate, + Read: resourceGkeonpremVmwareNodePoolRead, + Update: resourceGkeonpremVmwareNodePoolUpdate, + Delete: resourceGkeonpremVmwareNodePoolDelete, + + Importer: &schema.ResourceImporter{ + State: resourceGkeonpremVmwareNodePoolImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(60 * time.Minute), + Update: schema.DefaultTimeout(60 * time.Minute), + Delete: schema.DefaultTimeout(60 * time.Minute), + }, + + CustomizeDiff: customdiff.All( + tpgresource.SetAnnotationsDiff, + tpgresource.DefaultProviderProject, + ), + + Schema: map[string]*schema.Schema{ + "config": { + Type: schema.TypeList, + Required: true, + Description: `The node configuration of the node pool.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "image_type": { + Type: schema.TypeString, + Required: true, + Description: `The OS image to be used for each node in a node pool. +Currently 'cos', 'ubuntu', 'ubuntu_containerd' and 'windows' are supported.`, + }, + "boot_disk_size_gb": { + Type: schema.TypeInt, + Optional: true, + Description: `VMware disk size to be used during creation.`, + }, + "cpus": { + Type: schema.TypeInt, + Optional: true, + Description: `The number of CPUs for each node in the node pool.`, + Default: 4, + }, + "enable_load_balancer": { + Type: schema.TypeBool, + Optional: true, + Description: `Allow node pool traffic to be load balanced. Only works for clusters with +MetalLB load balancers.`, + }, + "image": { + Type: schema.TypeString, + Optional: true, + Description: `The OS image name in vCenter, only valid when using Windows.`, + }, + "labels": { + Type: schema.TypeMap, + Computed: true, + Optional: true, + Description: `The map of Kubernetes labels (key/value pairs) to be applied to each node. +These will added in addition to any default label(s) that +Kubernetes may apply to the node. +In case of conflict in label keys, the applied set may differ depending on +the Kubernetes version -- it's best to assume the behavior is undefined +and conflicts should be avoided.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "memory_mb": { + Type: schema.TypeInt, + Optional: true, + Description: `The megabytes of memory for each node in the node pool.`, + Default: 8192, + }, + "replicas": { + Type: schema.TypeInt, + Optional: true, + Description: `The number of nodes in the node pool.`, + Default: 1, + }, + "taints": { + Type: schema.TypeList, + Optional: true, + Description: `The initial taints assigned to nodes of this node pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Required: true, + Description: `Key associated with the effect.`, + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: `Value associated with the effect.`, + }, + "effect": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.ValidateEnum([]string{"EFFECT_UNSPECIFIED", "NO_SCHEDULE", "PREFER_NO_SCHEDULE", "NO_EXECUTE", ""}), + Description: `Available taint effects. Possible values: ["EFFECT_UNSPECIFIED", "NO_SCHEDULE", "PREFER_NO_SCHEDULE", "NO_EXECUTE"]`, + }, + }, + }, + }, + "vsphere_config": { + Type: schema.TypeList, + Computed: true, + Description: `Specifies the vSphere config for node pool.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "datastore": { + Type: schema.TypeString, + Computed: true, + Description: `The name of the vCenter datastore. Inherited from the user cluster.`, + }, + "tags": { + Type: schema.TypeList, + Computed: true, + Description: `Tags to apply to VMs.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "category": { + Type: schema.TypeString, + Computed: true, + Description: `The Vsphere tag category.`, + }, + "tag": { + Type: schema.TypeString, + Computed: true, + Description: `The Vsphere tag name.`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The location of the resource.`, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The vmware node pool name.`, + }, + "vmware_cluster": { + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName, + Description: `The cluster this node pool belongs to.`, + }, + "annotations": { + Type: schema.TypeMap, + Optional: true, + Description: `Annotations on the node Pool. +This field has the same restrictions as Kubernetes annotations. +The total size of all keys and values combined is limited to 256k. +Key can have 2 segments: prefix (optional) and name (required), +separated by a slash (/). +Prefix must be a DNS subdomain. +Name must be 63 characters or less, begin and end with alphanumerics, +with dashes (-), underscores (_), dots (.), and alphanumerics between. + + +**Note**: This field is non-authoritative, and will only manage the annotations present in your configuration. +Please refer to the field 'effective_annotations' for all of the annotations present on the resource.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "display_name": { + Type: schema.TypeString, + Optional: true, + Description: `The display name for the node pool.`, + }, + "node_pool_autoscaling": { + Type: schema.TypeList, + Optional: true, + Description: `Node Pool autoscaling config for the node pool.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "max_replicas": { + Type: schema.TypeInt, + Required: true, + Description: `Maximum number of replicas in the NodePool.`, + }, + "min_replicas": { + Type: schema.TypeInt, + Required: true, + Description: `Minimum number of replicas in the NodePool.`, + }, + }, + }, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was created, in RFC3339 text format.`, + }, + "delete_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was deleted, in RFC3339 text format.`, + }, + "effective_annotations": { + Type: schema.TypeMap, + Computed: true, + Description: `All of annotations (key/value pairs) present on the resource in GCP, including the annotations configured through Terraform, other clients and services.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "etag": { + Type: schema.TypeString, + Computed: true, + Description: `This checksum is computed by the server based on the value of other +fields, and may be sent on update and delete requests to ensure the +client has an up-to-date value before proceeding. +Allows clients to perform consistent read-modify-writes +through optimistic concurrency control.`, + }, + "on_prem_version": { + Type: schema.TypeString, + Computed: true, + Description: `Anthos version for the node pool. Defaults to the user cluster version.`, + }, + "reconciling": { + Type: schema.TypeBool, + Computed: true, + Description: `If set, there are currently changes in flight to the node pool.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The current state of this cluster.`, + }, + "status": { + Type: schema.TypeList, + Computed: true, + Description: `ResourceStatus representing detailed cluster state.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "conditions": { + Type: schema.TypeList, + Computed: true, + Description: `ResourceConditions provide a standard mechanism for higher-level status reporting from user cluster controller.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "last_transition_time": { + Type: schema.TypeString, + Computed: true, + Description: `Last time the condition transit from one status to another.`, + }, + "message": { + Type: schema.TypeString, + Computed: true, + Description: `Human-readable message indicating details about last transition.`, + }, + "reason": { + Type: schema.TypeString, + Computed: true, + Description: `Machine-readable message indicating details about last transition.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The lifecycle state of the condition.`, + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: `Type of the condition. +(e.g., ClusterRunning, NodePoolRunning or ServerSidePreflightReady)`, + }, + }, + }, + }, + "error_message": { + Type: schema.TypeString, + Computed: true, + Description: `Human-friendly representation of the error message from the user cluster +controller. The error message can be temporary as the user cluster +controller creates a cluster or node pool. If the error message persists +for a longer period of time, it can be used to surface error message to +indicate real problems requiring user intervention.`, + }, + }, + }, + }, + "uid": { + Type: schema.TypeString, + Computed: true, + Description: `The unique identifier of the node pool.`, + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time the cluster was last updated, in RFC3339 text format.`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + UseJSONNumber: true, + } +} + +func resourceGkeonpremVmwareNodePoolCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + displayNameProp, err := expandGkeonpremVmwareNodePoolDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + nodePoolAutoscalingProp, err := expandGkeonpremVmwareNodePoolNodePoolAutoscaling(d.Get("node_pool_autoscaling"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_pool_autoscaling"); !tpgresource.IsEmptyValue(reflect.ValueOf(nodePoolAutoscalingProp)) && (ok || !reflect.DeepEqual(v, nodePoolAutoscalingProp)) { + obj["nodePoolAutoscaling"] = nodePoolAutoscalingProp + } + configProp, err := expandGkeonpremVmwareNodePoolConfig(d.Get("config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("config"); !tpgresource.IsEmptyValue(reflect.ValueOf(configProp)) && (ok || !reflect.DeepEqual(v, configProp)) { + obj["config"] = configProp + } + annotationsProp, err := expandGkeonpremVmwareNodePoolEffectiveAnnotations(d.Get("effective_annotations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_annotations"); !tpgresource.IsEmptyValue(reflect.ValueOf(annotationsProp)) && (ok || !reflect.DeepEqual(v, annotationsProp)) { + obj["annotations"] = annotationsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/vmwareClusters/{{vmware_cluster}}/vmwareNodePools?vmware_node_pool_id={{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new VmwareNodePool: %#v", obj) + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for VmwareNodePool: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "POST", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutCreate), + }) + if err != nil { + return fmt.Errorf("Error creating VmwareNodePool: %s", err) + } + + // Store the ID now + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/vmwareClusters/{{vmware_cluster}}/vmwareNodePools/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + // Use the resource in the operation response to populate + // identity fields and d.Id() before read + var opRes map[string]interface{} + err = GkeonpremOperationWaitTimeWithResponse( + config, res, &opRes, project, "Creating VmwareNodePool", userAgent, + d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error waiting to create VmwareNodePool: %s", err) + } + + // This may have caused the ID to update - update it if so. + id, err = tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/vmwareClusters/{{vmware_cluster}}/vmwareNodePools/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating VmwareNodePool %q: %#v", d.Id(), res) + + return resourceGkeonpremVmwareNodePoolRead(d, meta) +} + +func resourceGkeonpremVmwareNodePoolRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/vmwareClusters/{{vmware_cluster}}/vmwareNodePools/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for VmwareNodePool: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("GkeonpremVmwareNodePool %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + + if err := d.Set("display_name", flattenGkeonpremVmwareNodePoolDisplayName(res["displayName"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("annotations", flattenGkeonpremVmwareNodePoolAnnotations(res["annotations"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("node_pool_autoscaling", flattenGkeonpremVmwareNodePoolNodePoolAutoscaling(res["nodePoolAutoscaling"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("config", flattenGkeonpremVmwareNodePoolConfig(res["config"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("status", flattenGkeonpremVmwareNodePoolStatus(res["status"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("uid", flattenGkeonpremVmwareNodePoolUid(res["uid"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("state", flattenGkeonpremVmwareNodePoolState(res["state"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("reconciling", flattenGkeonpremVmwareNodePoolReconciling(res["reconciling"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("create_time", flattenGkeonpremVmwareNodePoolCreateTime(res["createTime"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("update_time", flattenGkeonpremVmwareNodePoolUpdateTime(res["updateTime"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("delete_time", flattenGkeonpremVmwareNodePoolDeleteTime(res["deleteTime"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("etag", flattenGkeonpremVmwareNodePoolEtag(res["etag"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("on_prem_version", flattenGkeonpremVmwareNodePoolOnPremVersion(res["onPremVersion"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + if err := d.Set("effective_annotations", flattenGkeonpremVmwareNodePoolEffectiveAnnotations(res["annotations"], d, config)); err != nil { + return fmt.Errorf("Error reading VmwareNodePool: %s", err) + } + + return nil +} + +func resourceGkeonpremVmwareNodePoolUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for VmwareNodePool: %s", err) + } + billingProject = project + + obj := make(map[string]interface{}) + displayNameProp, err := expandGkeonpremVmwareNodePoolDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + nodePoolAutoscalingProp, err := expandGkeonpremVmwareNodePoolNodePoolAutoscaling(d.Get("node_pool_autoscaling"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("node_pool_autoscaling"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nodePoolAutoscalingProp)) { + obj["nodePoolAutoscaling"] = nodePoolAutoscalingProp + } + configProp, err := expandGkeonpremVmwareNodePoolConfig(d.Get("config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("config"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, configProp)) { + obj["config"] = configProp + } + annotationsProp, err := expandGkeonpremVmwareNodePoolEffectiveAnnotations(d.Get("effective_annotations"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("effective_annotations"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, annotationsProp)) { + obj["annotations"] = annotationsProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/vmwareClusters/{{vmware_cluster}}/vmwareNodePools/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating VmwareNodePool %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("display_name") { + updateMask = append(updateMask, "displayName") + } + + if d.HasChange("node_pool_autoscaling") { + updateMask = append(updateMask, "nodePoolAutoscaling") + } + + if d.HasChange("config") { + updateMask = append(updateMask, "config") + } + + if d.HasChange("effective_annotations") { + updateMask = append(updateMask, "annotations") + } + // updateMask is a URL parameter but not present in the schema, so ReplaceVars + // won't set it + url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + // if updateMask is empty we are not updating anything so skip the post + if len(updateMask) > 0 { + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "PATCH", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutUpdate), + }) + + if err != nil { + return fmt.Errorf("Error updating VmwareNodePool %q: %s", d.Id(), err) + } else { + log.Printf("[DEBUG] Finished updating VmwareNodePool %q: %#v", d.Id(), res) + } + + err = GkeonpremOperationWaitTime( + config, res, project, "Updating VmwareNodePool", userAgent, + d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return err + } + } + + return resourceGkeonpremVmwareNodePoolRead(d, meta) +} + +func resourceGkeonpremVmwareNodePoolDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for VmwareNodePool: %s", err) + } + billingProject = project + + url, err := tpgresource.ReplaceVars(d, config, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/vmwareClusters/{{vmware_cluster}}/vmwareNodePools/{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting VmwareNodePool %q", d.Id()) + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutDelete), + }) + if err != nil { + return transport_tpg.HandleNotFoundError(err, d, "VmwareNodePool") + } + + err = GkeonpremOperationWaitTime( + config, res, project, "Deleting VmwareNodePool", userAgent, + d.Timeout(schema.TimeoutDelete)) + + if err != nil { + return err + } + + log.Printf("[DEBUG] Finished deleting VmwareNodePool %q: %#v", d.Id(), res) + return nil +} + +func resourceGkeonpremVmwareNodePoolImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*transport_tpg.Config) + if err := tpgresource.ParseImportId([]string{ + "^projects/(?P[^/]+)/locations/(?P[^/]+)/vmwareClusters/(?P[^/]+)/vmwareNodePools/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)/(?P[^/]+)$", + "^(?P[^/]+)/(?P[^/]+)/(?P[^/]+)$", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := tpgresource.ReplaceVars(d, config, "projects/{{project}}/locations/{{location}}/vmwareClusters/{{vmware_cluster}}/vmwareNodePools/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenGkeonpremVmwareNodePoolDisplayName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return v + } + + transformed := make(map[string]interface{}) + if l, ok := d.GetOkExists("annotations"); ok { + for k := range l.(map[string]interface{}) { + transformed[k] = v.(map[string]interface{})[k] + } + } + + return transformed +} + +func flattenGkeonpremVmwareNodePoolNodePoolAutoscaling(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_replicas"] = + flattenGkeonpremVmwareNodePoolNodePoolAutoscalingMinReplicas(original["minReplicas"], d, config) + transformed["max_replicas"] = + flattenGkeonpremVmwareNodePoolNodePoolAutoscalingMaxReplicas(original["maxReplicas"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareNodePoolNodePoolAutoscalingMinReplicas(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 flattenGkeonpremVmwareNodePoolNodePoolAutoscalingMaxReplicas(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 flattenGkeonpremVmwareNodePoolConfig(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["cpus"] = + flattenGkeonpremVmwareNodePoolConfigCpus(original["cpus"], d, config) + transformed["memory_mb"] = + flattenGkeonpremVmwareNodePoolConfigMemoryMb(original["memoryMb"], d, config) + transformed["replicas"] = + flattenGkeonpremVmwareNodePoolConfigReplicas(original["replicas"], d, config) + transformed["image_type"] = + flattenGkeonpremVmwareNodePoolConfigImageType(original["imageType"], d, config) + transformed["image"] = + flattenGkeonpremVmwareNodePoolConfigImage(original["image"], d, config) + transformed["boot_disk_size_gb"] = + flattenGkeonpremVmwareNodePoolConfigBootDiskSizeGb(original["bootDiskSizeGb"], d, config) + transformed["taints"] = + flattenGkeonpremVmwareNodePoolConfigTaints(original["taints"], d, config) + transformed["labels"] = + flattenGkeonpremVmwareNodePoolConfigLabels(original["labels"], d, config) + transformed["vsphere_config"] = + flattenGkeonpremVmwareNodePoolConfigVsphereConfig(original["vsphereConfig"], d, config) + transformed["enable_load_balancer"] = + flattenGkeonpremVmwareNodePoolConfigEnableLoadBalancer(original["enableLoadBalancer"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareNodePoolConfigCpus(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 flattenGkeonpremVmwareNodePoolConfigMemoryMb(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 flattenGkeonpremVmwareNodePoolConfigReplicas(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 flattenGkeonpremVmwareNodePoolConfigImageType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolConfigImage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolConfigBootDiskSizeGb(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 flattenGkeonpremVmwareNodePoolConfigTaints(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{}{ + "key": flattenGkeonpremVmwareNodePoolConfigTaintsKey(original["key"], d, config), + "value": flattenGkeonpremVmwareNodePoolConfigTaintsValue(original["value"], d, config), + "effect": flattenGkeonpremVmwareNodePoolConfigTaintsEffect(original["effect"], d, config), + }) + } + return transformed +} +func flattenGkeonpremVmwareNodePoolConfigTaintsKey(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolConfigTaintsValue(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolConfigTaintsEffect(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolConfigLabels(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolConfigVsphereConfig(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["datastore"] = + flattenGkeonpremVmwareNodePoolConfigVsphereConfigDatastore(original["datastore"], d, config) + transformed["tags"] = + flattenGkeonpremVmwareNodePoolConfigVsphereConfigTags(original["tags"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareNodePoolConfigVsphereConfigDatastore(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolConfigVsphereConfigTags(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{}{ + "category": flattenGkeonpremVmwareNodePoolConfigVsphereConfigTagsCategory(original["category"], d, config), + "tag": flattenGkeonpremVmwareNodePoolConfigVsphereConfigTagsTag(original["tag"], d, config), + }) + } + return transformed +} +func flattenGkeonpremVmwareNodePoolConfigVsphereConfigTagsCategory(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolConfigVsphereConfigTagsTag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolConfigEnableLoadBalancer(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolStatus(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["error_message"] = + flattenGkeonpremVmwareNodePoolStatusErrorMessage(original["errorMessage"], d, config) + transformed["conditions"] = + flattenGkeonpremVmwareNodePoolStatusConditions(original["conditions"], d, config) + return []interface{}{transformed} +} +func flattenGkeonpremVmwareNodePoolStatusErrorMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolStatusConditions(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{}{ + "type": flattenGkeonpremVmwareNodePoolStatusConditionsType(original["type"], d, config), + "reason": flattenGkeonpremVmwareNodePoolStatusConditionsReason(original["reason"], d, config), + "message": flattenGkeonpremVmwareNodePoolStatusConditionsMessage(original["message"], d, config), + "last_transition_time": flattenGkeonpremVmwareNodePoolStatusConditionsLastTransitionTime(original["lastTransitionTime"], d, config), + "state": flattenGkeonpremVmwareNodePoolStatusConditionsState(original["state"], d, config), + }) + } + return transformed +} +func flattenGkeonpremVmwareNodePoolStatusConditionsType(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolStatusConditionsReason(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolStatusConditionsMessage(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolStatusConditionsLastTransitionTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolStatusConditionsState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolUid(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolState(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolReconciling(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolUpdateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolDeleteTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolEtag(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolOnPremVersion(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenGkeonpremVmwareNodePoolEffectiveAnnotations(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func expandGkeonpremVmwareNodePoolDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolNodePoolAutoscaling(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{}) + + transformedMinReplicas, err := expandGkeonpremVmwareNodePoolNodePoolAutoscalingMinReplicas(original["min_replicas"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMinReplicas); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["minReplicas"] = transformedMinReplicas + } + + transformedMaxReplicas, err := expandGkeonpremVmwareNodePoolNodePoolAutoscalingMaxReplicas(original["max_replicas"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxReplicas); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["maxReplicas"] = transformedMaxReplicas + } + + return transformed, nil +} + +func expandGkeonpremVmwareNodePoolNodePoolAutoscalingMinReplicas(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolNodePoolAutoscalingMaxReplicas(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfig(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{}) + + transformedCpus, err := expandGkeonpremVmwareNodePoolConfigCpus(original["cpus"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCpus); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["cpus"] = transformedCpus + } + + transformedMemoryMb, err := expandGkeonpremVmwareNodePoolConfigMemoryMb(original["memory_mb"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMemoryMb); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["memoryMb"] = transformedMemoryMb + } + + transformedReplicas, err := expandGkeonpremVmwareNodePoolConfigReplicas(original["replicas"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedReplicas); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["replicas"] = transformedReplicas + } + + transformedImageType, err := expandGkeonpremVmwareNodePoolConfigImageType(original["image_type"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedImageType); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["imageType"] = transformedImageType + } + + transformedImage, err := expandGkeonpremVmwareNodePoolConfigImage(original["image"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedImage); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["image"] = transformedImage + } + + transformedBootDiskSizeGb, err := expandGkeonpremVmwareNodePoolConfigBootDiskSizeGb(original["boot_disk_size_gb"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedBootDiskSizeGb); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["bootDiskSizeGb"] = transformedBootDiskSizeGb + } + + transformedTaints, err := expandGkeonpremVmwareNodePoolConfigTaints(original["taints"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTaints); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["taints"] = transformedTaints + } + + transformedLabels, err := expandGkeonpremVmwareNodePoolConfigLabels(original["labels"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLabels); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["labels"] = transformedLabels + } + + transformedVsphereConfig, err := expandGkeonpremVmwareNodePoolConfigVsphereConfig(original["vsphere_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedVsphereConfig); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["vsphereConfig"] = transformedVsphereConfig + } + + transformedEnableLoadBalancer, err := expandGkeonpremVmwareNodePoolConfigEnableLoadBalancer(original["enable_load_balancer"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEnableLoadBalancer); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["enableLoadBalancer"] = transformedEnableLoadBalancer + } + + return transformed, nil +} + +func expandGkeonpremVmwareNodePoolConfigCpus(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigMemoryMb(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigReplicas(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigImageType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigImage(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigBootDiskSizeGb(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigTaints(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{}) + + transformedKey, err := expandGkeonpremVmwareNodePoolConfigTaintsKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedValue, err := expandGkeonpremVmwareNodePoolConfigTaintsValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["value"] = transformedValue + } + + transformedEffect, err := expandGkeonpremVmwareNodePoolConfigTaintsEffect(original["effect"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEffect); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["effect"] = transformedEffect + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremVmwareNodePoolConfigTaintsKey(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigTaintsValue(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigTaintsEffect(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandGkeonpremVmwareNodePoolConfigVsphereConfig(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{}) + + transformedDatastore, err := expandGkeonpremVmwareNodePoolConfigVsphereConfigDatastore(original["datastore"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDatastore); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["datastore"] = transformedDatastore + } + + transformedTags, err := expandGkeonpremVmwareNodePoolConfigVsphereConfigTags(original["tags"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTags); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["tags"] = transformedTags + } + + return transformed, nil +} + +func expandGkeonpremVmwareNodePoolConfigVsphereConfigDatastore(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigVsphereConfigTags(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{}) + + transformedCategory, err := expandGkeonpremVmwareNodePoolConfigVsphereConfigTagsCategory(original["category"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCategory); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["category"] = transformedCategory + } + + transformedTag, err := expandGkeonpremVmwareNodePoolConfigVsphereConfigTagsTag(original["tag"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedTag); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["tag"] = transformedTag + } + + req = append(req, transformed) + } + return req, nil +} + +func expandGkeonpremVmwareNodePoolConfigVsphereConfigTagsCategory(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigVsphereConfigTagsTag(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolConfigEnableLoadBalancer(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandGkeonpremVmwareNodePoolEffectiveAnnotations(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} diff --git a/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_generated_test.go b/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_generated_test.go new file mode 100644 index 00000000000..7752421fea6 --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_generated_test.go @@ -0,0 +1,245 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func TestAccGkeonpremVmwareNodePool_gkeonpremVmwareNodePoolBasicExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremVmwareNodePoolDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremVmwareNodePool_gkeonpremVmwareNodePoolBasicExample(context), + }, + { + ResourceName: "google_gkeonprem_vmware_node_pool.nodepool-basic", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "vmware_cluster", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremVmwareNodePool_gkeonpremVmwareNodePoolBasicExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_vmware_cluster" "default-basic" { + name = "tf-test-my-cluster%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + dhcp_ip_config { + enabled = true + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + metal_lb_config { + address_pools { + pool = "ingress-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + } + address_pools { + pool = "lb-test-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + } + } + } +} + +resource "google_gkeonprem_vmware_node_pool" "nodepool-basic" { + name = "tf-test-my-nodepool%{random_suffix}" + location = "us-west1" + vmware_cluster = google_gkeonprem_vmware_cluster.default-basic.name + config { + replicas = 3 + image_type = "ubuntu_containerd" + enable_load_balancer = true + } +} +`, context) +} + +func TestAccGkeonpremVmwareNodePool_gkeonpremVmwareNodePoolFullExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremVmwareNodePoolDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremVmwareNodePool_gkeonpremVmwareNodePoolFullExample(context), + }, + { + ResourceName: "google_gkeonprem_vmware_node_pool.nodepool-full", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "vmware_cluster", "location", "annotations"}, + }, + }, + }) +} + +func testAccGkeonpremVmwareNodePool_gkeonpremVmwareNodePoolFullExample(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_gkeonprem_vmware_cluster" "default-full" { + name = "tf-test-my-cluster%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + dhcp_ip_config { + enabled = true + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + metal_lb_config { + address_pools { + pool = "ingress-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + } + address_pools { + pool = "lb-test-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + } + } + } +} + +resource "google_gkeonprem_vmware_node_pool" "nodepool-full" { + name = "tf-test-my-nodepool%{random_suffix}" + location = "us-west1" + vmware_cluster = google_gkeonprem_vmware_cluster.default-full.name + annotations = {} + config { + cpus = 4 + memory_mb = 8196 + replicas = 3 + image_type = "ubuntu_containerd" + image = "image" + boot_disk_size_gb = 10 + taints { + key = "key" + value = "value" + } + taints { + key = "key" + value = "value" + effect = "NO_SCHEDULE" + } + labels = {} + enable_load_balancer = true + } + node_pool_autoscaling { + min_replicas = 1 + max_replicas = 5 + } +} +`, context) +} + +func testAccCheckGkeonpremVmwareNodePoolDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_gkeonprem_vmware_node_pool" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{GkeonpremBasePath}}projects/{{project}}/locations/{{location}}/vmwareClusters/{{vmware_cluster}}/vmwareNodePools/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("GkeonpremVmwareNodePool still exists at %s", url) + } + } + + return nil + } +} diff --git a/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_sweeper.go b/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_sweeper.go new file mode 100644 index 00000000000..ebccbd3de9f --- /dev/null +++ b/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_sweeper.go @@ -0,0 +1,139 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package gkeonprem + +import ( + "context" + "log" + "strings" + "testing" + + "github.com/hashicorp/terraform-provider-google/google/envvar" + "github.com/hashicorp/terraform-provider-google/google/sweeper" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func init() { + sweeper.AddTestSweepers("GkeonpremVmwareNodePool", testSweepGkeonpremVmwareNodePool) +} + +// At the time of writing, the CI only passes us-central1 as the region +func testSweepGkeonpremVmwareNodePool(region string) error { + resourceName := "GkeonpremVmwareNodePool" + log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) + + config, err := sweeper.SharedConfigForRegion(region) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) + return err + } + + err = config.LoadAndValidate(context.Background()) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) + return err + } + + t := &testing.T{} + billingId := envvar.GetTestBillingAccountFromEnv(t) + + // Setup variables to replace in list template + d := &tpgresource.ResourceDataMock{ + FieldsInSchema: map[string]interface{}{ + "project": config.Project, + "region": region, + "location": region, + "zone": "-", + "billing_account": billingId, + }, + } + + listTemplate := strings.Split("https://gkeonprem.googleapis.com/v1/projects/{{project}}/locations/{{location}}/vmwareClusters/{{vmware_cluster}}/vmwareNodePools", "?")[0] + listUrl, err := tpgresource.ReplaceVars(d, config, listTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) + return nil + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: config.Project, + RawURL: listUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) + return nil + } + + resourceList, ok := res["vmwareNodePools"] + if !ok { + log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") + return nil + } + + rl := resourceList.([]interface{}) + + log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) + // Keep count of items that aren't sweepable for logging. + nonPrefixCount := 0 + for _, ri := range rl { + obj := ri.(map[string]interface{}) + if obj["name"] == nil { + log.Printf("[INFO][SWEEPER_LOG] %s resource name was nil", resourceName) + return nil + } + + name := tpgresource.GetResourceNameFromSelfLink(obj["name"].(string)) + // Skip resources that shouldn't be sweeped + if !sweeper.IsSweepableTestResource(name) { + nonPrefixCount++ + continue + } + + deleteTemplate := "https://gkeonprem.googleapis.com/v1/projects/{{project}}/locations/{{location}}/vmwareClusters/{{vmware_cluster}}/vmwareNodePools/{{name}}" + deleteUrl, err := tpgresource.ReplaceVars(d, config, deleteTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) + return nil + } + deleteUrl = deleteUrl + name + + // Don't wait on operations as we may have a lot to delete + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "DELETE", + Project: config.Project, + RawURL: deleteUrl, + UserAgent: config.UserAgent, + }) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) + } else { + log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) + } + } + + if nonPrefixCount > 0 { + log.Printf("[INFO][SWEEPER_LOG] %d items were non-sweepable and skipped.", nonPrefixCount) + } + + return nil +} diff --git a/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_test.go b/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_test.go index 0ad9b6a9bdd..00f2ac6a722 100644 --- a/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_test.go +++ b/google/services/gkeonprem/resource_gkeonprem_vmware_node_pool_test.go @@ -1,3 +1,190 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package gkeonprem_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccGkeonpremVmwareNodePool_vmwareNodePoolUpdate(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckGkeonpremVmwareNodePoolDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccGkeonpremVmwareNodePool_vmwareNodePoolUpdateStart(context), + }, + { + ResourceName: "google_gkeonprem_vmware_node_pool.nodepool", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, + }, + { + Config: testAccGkeonpremVmwareNodePool_vmwareNodePoolUpdate(context), + }, + { + ResourceName: "google_gkeonprem_vmware_node_pool.nodepool", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"annotations"}, + }, + }, + }) +} + +func testAccGkeonpremVmwareNodePool_vmwareNodePoolUpdateStart(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_vmware_cluster" "cluster" { + name = "tf-test-cluster-%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + annotations = {} + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + dhcp_ip_config { + enabled = true + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + metal_lb_config { + address_pools { + pool = "ingress-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + avoid_buggy_ips = true + } + address_pools { + pool = "lb-test-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + avoid_buggy_ips = true + } + } + } + } + + resource "google_gkeonprem_vmware_node_pool" "nodepool" { + name = "tf-test-nodepool-%{random_suffix}" + location = "us-west1" + vmware_cluster = google_gkeonprem_vmware_cluster.cluster.name + annotations = { + env = "test" + } + config { + cpus = 4 + memory_mb = 8196 + replicas = 3 + image_type = "ubuntu_containerd" + image = "image" + boot_disk_size_gb = 10 + taints { + key = "key" + value = "value" + } + labels = {} + enable_load_balancer = true + } + node_pool_autoscaling { + min_replicas = 1 + max_replicas = 5 + } + } +`, context) +} + +func testAccGkeonpremVmwareNodePool_vmwareNodePoolUpdate(context map[string]interface{}) string { + return acctest.Nprintf(` + + resource "google_gkeonprem_vmware_cluster" "cluster" { + name = "tf-test-cluster-%{random_suffix}" + location = "us-west1" + admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" + description = "test cluster" + on_prem_version = "1.13.1-gke.35" + annotations = {} + network_config { + service_address_cidr_blocks = ["10.96.0.0/12"] + pod_address_cidr_blocks = ["192.168.0.0/16"] + dhcp_ip_config { + enabled = true + } + } + control_plane_node { + cpus = 4 + memory = 8192 + replicas = 1 + } + load_balancer { + vip_config { + control_plane_vip = "10.251.133.5" + ingress_vip = "10.251.135.19" + } + metal_lb_config { + address_pools { + pool = "ingress-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + avoid_buggy_ips = true + } + address_pools { + pool = "lb-test-ip" + manual_assign = "true" + addresses = ["10.251.135.19"] + avoid_buggy_ips = true + } + } + } + } + + resource "google_gkeonprem_vmware_node_pool" "nodepool" { + name = "tf-test-nodepool-%{random_suffix}" + location = "us-west1" + vmware_cluster = google_gkeonprem_vmware_cluster.cluster.name + annotations = { + env = "test-update" + } + config { + cpus = 5 + memory_mb = 4096 + replicas = 3 + image_type = "windows" + image = "image-updated" + boot_disk_size_gb = 12 + taints { + key = "key-updated" + value = "value-updated" + } + labels = {} + enable_load_balancer = false + } + node_pool_autoscaling { + min_replicas = 2 + max_replicas = 6 + } + } +`, context) +} diff --git a/google/sweeper/gcp_sweeper_test.go b/google/sweeper/gcp_sweeper_test.go index 210af1d01ab..3f77f1603c4 100644 --- a/google/sweeper/gcp_sweeper_test.go +++ b/google/sweeper/gcp_sweeper_test.go @@ -65,6 +65,7 @@ import ( _ "github.com/hashicorp/terraform-provider-google/google/services/gkebackup" _ "github.com/hashicorp/terraform-provider-google/google/services/gkehub" _ "github.com/hashicorp/terraform-provider-google/google/services/gkehub2" + _ "github.com/hashicorp/terraform-provider-google/google/services/gkeonprem" _ "github.com/hashicorp/terraform-provider-google/google/services/healthcare" _ "github.com/hashicorp/terraform-provider-google/google/services/iam2" _ "github.com/hashicorp/terraform-provider-google/google/services/iambeta" diff --git a/google/transport/config.go b/google/transport/config.go index 94555bbaa12..0c60c5d27c6 100644 --- a/google/transport/config.go +++ b/google/transport/config.go @@ -241,6 +241,7 @@ type Config struct { GKEBackupBasePath string GKEHubBasePath string GKEHub2BasePath string + GkeonpremBasePath string HealthcareBasePath string IAM2BasePath string IAMBetaBasePath string @@ -361,6 +362,7 @@ const FirestoreBasePathKey = "Firestore" const GKEBackupBasePathKey = "GKEBackup" const GKEHubBasePathKey = "GKEHub" const GKEHub2BasePathKey = "GKEHub2" +const GkeonpremBasePathKey = "Gkeonprem" const HealthcareBasePathKey = "Healthcare" const IAM2BasePathKey = "IAM2" const IAMBetaBasePathKey = "IAMBeta" @@ -475,6 +477,7 @@ var DefaultBasePaths = map[string]string{ GKEBackupBasePathKey: "https://gkebackup.googleapis.com/v1/", GKEHubBasePathKey: "https://gkehub.googleapis.com/v1/", GKEHub2BasePathKey: "https://gkehub.googleapis.com/v1/", + GkeonpremBasePathKey: "https://gkeonprem.googleapis.com/v1/", HealthcareBasePathKey: "https://healthcare.googleapis.com/v1/", IAM2BasePathKey: "https://iam.googleapis.com/v2/", IAMBetaBasePathKey: "https://iam.googleapis.com/v1/", @@ -884,6 +887,11 @@ func HandleSDKDefaults(d *schema.ResourceData) error { "GOOGLE_GKE_HUB2_CUSTOM_ENDPOINT", }, DefaultBasePaths[GKEHub2BasePathKey])) } + if d.Get("gkeonprem_custom_endpoint") == "" { + d.Set("gkeonprem_custom_endpoint", MultiEnvDefault([]string{ + "GOOGLE_GKEONPREM_CUSTOM_ENDPOINT", + }, DefaultBasePaths[GkeonpremBasePathKey])) + } if d.Get("healthcare_custom_endpoint") == "" { d.Set("healthcare_custom_endpoint", MultiEnvDefault([]string{ "GOOGLE_HEALTHCARE_CUSTOM_ENDPOINT", @@ -1987,6 +1995,7 @@ func ConfigureBasePaths(c *Config) { c.GKEBackupBasePath = DefaultBasePaths[GKEBackupBasePathKey] c.GKEHubBasePath = DefaultBasePaths[GKEHubBasePathKey] c.GKEHub2BasePath = DefaultBasePaths[GKEHub2BasePathKey] + c.GkeonpremBasePath = DefaultBasePaths[GkeonpremBasePathKey] c.HealthcareBasePath = DefaultBasePaths[HealthcareBasePathKey] c.IAM2BasePath = DefaultBasePaths[IAM2BasePathKey] c.IAMBetaBasePath = DefaultBasePaths[IAMBetaBasePathKey] diff --git a/website/docs/r/gkeonprem_bare_metal_admin_cluster.html.markdown b/website/docs/r/gkeonprem_bare_metal_admin_cluster.html.markdown index 9b9e2984928..4c8c9ae9278 100644 --- a/website/docs/r/gkeonprem_bare_metal_admin_cluster.html.markdown +++ b/website/docs/r/gkeonprem_bare_metal_admin_cluster.html.markdown @@ -21,8 +21,6 @@ description: |- A Google Bare Metal Admin Cluster. -~> **Warning:** This resource is in beta, and should be used with the terraform-provider-google-beta provider. -See [Provider Versions](https://terraform.io/docs/providers/google/guides/provider_versions.html) for more details on beta resources. ## Example Usage - Gkeonprem Bare Metal Admin Cluster Basic @@ -30,7 +28,6 @@ See [Provider Versions](https://terraform.io/docs/providers/google/guides/provid ```hcl resource "google_gkeonprem_bare_metal_admin_cluster" "admin-cluster-basic" { - provider = google-beta name = "my-cluster" location = "us-west1" bare_metal_version = "1.13.4" @@ -94,7 +91,6 @@ resource "google_gkeonprem_bare_metal_admin_cluster" "admin-cluster-basic" { ```hcl resource "google_gkeonprem_bare_metal_admin_cluster" "admin-cluster-basic" { - provider = google-beta name = "my-cluster" location = "us-west1" description = "test description" diff --git a/website/docs/r/gkeonprem_bare_metal_cluster.html.markdown b/website/docs/r/gkeonprem_bare_metal_cluster.html.markdown index 20e356a6cfa..7393dbea1ef 100644 --- a/website/docs/r/gkeonprem_bare_metal_cluster.html.markdown +++ b/website/docs/r/gkeonprem_bare_metal_cluster.html.markdown @@ -21,8 +21,6 @@ description: |- A Google Bare Metal User Cluster. -~> **Warning:** This resource is in beta, and should be used with the terraform-provider-google-beta provider. -See [Provider Versions](https://terraform.io/docs/providers/google/guides/provider_versions.html) for more details on beta resources. ## Example Usage - Gkeonprem Bare Metal Cluster Basic @@ -30,7 +28,6 @@ See [Provider Versions](https://terraform.io/docs/providers/google/guides/provid ```hcl resource "google_gkeonprem_bare_metal_cluster" "cluster-basic" { - provider = google-beta name = "my-cluster" location = "us-west1" admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" @@ -107,7 +104,6 @@ resource "google_gkeonprem_bare_metal_cluster" "cluster-basic" { ```hcl resource "google_gkeonprem_bare_metal_cluster" "cluster-manuallb" { - provider = google-beta name = "cluster-manuallb" location = "us-west1" admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" @@ -175,7 +171,6 @@ resource "google_gkeonprem_bare_metal_cluster" "cluster-manuallb" { ```hcl resource "google_gkeonprem_bare_metal_cluster" "cluster-bgplb" { - provider = google-beta name = "cluster-bgplb" location = "us-west1" admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" diff --git a/website/docs/r/gkeonprem_bare_metal_node_pool.html.markdown b/website/docs/r/gkeonprem_bare_metal_node_pool.html.markdown index 1f13ec1ba76..3cac56abd3b 100644 --- a/website/docs/r/gkeonprem_bare_metal_node_pool.html.markdown +++ b/website/docs/r/gkeonprem_bare_metal_node_pool.html.markdown @@ -21,8 +21,6 @@ description: |- A Google Bare Metal Node Pool. -~> **Warning:** This resource is in beta, and should be used with the terraform-provider-google-beta provider. -See [Provider Versions](https://terraform.io/docs/providers/google/guides/provider_versions.html) for more details on beta resources. ## Example Usage - Gkeonprem Bare Metal Node Pool Basic @@ -30,7 +28,6 @@ See [Provider Versions](https://terraform.io/docs/providers/google/guides/provid ```hcl resource "google_gkeonprem_bare_metal_cluster" "default-basic" { - provider = google-beta name = "my-cluster" location = "us-west1" admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" @@ -101,7 +98,6 @@ resource "google_gkeonprem_bare_metal_cluster" "default-basic" { } resource "google_gkeonprem_bare_metal_node_pool" "nodepool-basic" { - provider = google-beta name = "my-nodepool" bare_metal_cluster = google_gkeonprem_bare_metal_cluster.default-basic.name location = "us-west1" @@ -118,7 +114,6 @@ resource "google_gkeonprem_bare_metal_node_pool" "nodepool-basic" { ```hcl resource "google_gkeonprem_bare_metal_cluster" "default-full" { - provider = google-beta name = "my-cluster" location = "us-west1" admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" @@ -189,7 +184,6 @@ resource "google_gkeonprem_bare_metal_cluster" "default-full" { } resource "google_gkeonprem_bare_metal_node_pool" "nodepool-full" { - provider = google-beta name = "my-nodepool" display_name = "test-name" bare_metal_cluster = google_gkeonprem_bare_metal_cluster.default-full.name diff --git a/website/docs/r/gkeonprem_vmware_cluster.html.markdown b/website/docs/r/gkeonprem_vmware_cluster.html.markdown index 5b134b3a3f4..d9a9cb52245 100644 --- a/website/docs/r/gkeonprem_vmware_cluster.html.markdown +++ b/website/docs/r/gkeonprem_vmware_cluster.html.markdown @@ -21,8 +21,6 @@ description: |- A Google VMware User Cluster. -~> **Warning:** This resource is in beta, and should be used with the terraform-provider-google-beta provider. -See [Provider Versions](https://terraform.io/docs/providers/google/guides/provider_versions.html) for more details on beta resources. ## Example Usage - Gkeonprem Vmware Cluster Basic @@ -30,7 +28,6 @@ See [Provider Versions](https://terraform.io/docs/providers/google/guides/provid ```hcl resource "google_gkeonprem_vmware_cluster" "cluster-basic" { - provider = google-beta name = "cluster-basic" location = "us-west1" admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" @@ -76,7 +73,6 @@ resource "google_gkeonprem_vmware_cluster" "cluster-basic" { ```hcl resource "google_gkeonprem_vmware_cluster" "cluster-f5lb" { - provider = google-beta name = "cluster-f5lb" location = "us-west1" admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" @@ -147,7 +143,6 @@ resource "google_gkeonprem_vmware_cluster" "cluster-f5lb" { ```hcl resource "google_gkeonprem_vmware_cluster" "cluster-manuallb" { - provider = google-beta name = "cluster-manuallb" location = "us-west1" admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" diff --git a/website/docs/r/gkeonprem_vmware_node_pool.html.markdown b/website/docs/r/gkeonprem_vmware_node_pool.html.markdown index be25273418e..7129d1122a4 100644 --- a/website/docs/r/gkeonprem_vmware_node_pool.html.markdown +++ b/website/docs/r/gkeonprem_vmware_node_pool.html.markdown @@ -21,8 +21,6 @@ description: |- A Google Vmware Node Pool. -~> **Warning:** This resource is in beta, and should be used with the terraform-provider-google-beta provider. -See [Provider Versions](https://terraform.io/docs/providers/google/guides/provider_versions.html) for more details on beta resources. ## Example Usage - Gkeonprem Vmware Node Pool Basic @@ -30,7 +28,6 @@ See [Provider Versions](https://terraform.io/docs/providers/google/guides/provid ```hcl resource "google_gkeonprem_vmware_cluster" "default-basic" { - provider = google-beta name = "my-cluster" location = "us-west1" admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" @@ -69,7 +66,6 @@ resource "google_gkeonprem_vmware_cluster" "default-basic" { } resource "google_gkeonprem_vmware_node_pool" "nodepool-basic" { - provider = google-beta name = "my-nodepool" location = "us-west1" vmware_cluster = google_gkeonprem_vmware_cluster.default-basic.name @@ -85,7 +81,6 @@ resource "google_gkeonprem_vmware_node_pool" "nodepool-basic" { ```hcl resource "google_gkeonprem_vmware_cluster" "default-full" { - provider = google-beta name = "my-cluster" location = "us-west1" admin_cluster_membership = "projects/870316890899/locations/global/memberships/gkeonprem-terraform-test" @@ -124,7 +119,6 @@ resource "google_gkeonprem_vmware_cluster" "default-full" { } resource "google_gkeonprem_vmware_node_pool" "nodepool-full" { - provider = google-beta name = "my-nodepool" location = "us-west1" vmware_cluster = google_gkeonprem_vmware_cluster.default-full.name