From 3bd69769169c7165f1cbca74cdfc7afdf343ce0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Gergely?= Date: Tue, 21 Nov 2023 14:18:29 +0100 Subject: [PATCH] CDPCP-10932 - GCP environment creation Terraform Resource fails due to unknown values on some parameters --- resources/environments/converter_common.go | 55 ++++++++ .../environments/converter_common_test.go | 119 ++++++++++++++++++ resources/environments/converter_gcp.go | 7 ++ .../environments/model_common_environment.go | 36 ++++++ .../environments/model_gcp_environment.go | 7 +- utils/utils.go | 22 ++++ 6 files changed, 243 insertions(+), 3 deletions(-) create mode 100644 resources/environments/converter_common.go create mode 100644 resources/environments/converter_common_test.go create mode 100644 resources/environments/model_common_environment.go diff --git a/resources/environments/converter_common.go b/resources/environments/converter_common.go new file mode 100644 index 00000000..28e599ad --- /dev/null +++ b/resources/environments/converter_common.go @@ -0,0 +1,55 @@ +// Copyright 2023 Cloudera. All Rights Reserved. +// +// This file is licensed under the Apache License Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// +// This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. Refer to the License for the specific +// permissions and limitations governing your use of the file. + +package environments + +import ( + "github.com/hashicorp/terraform-plugin-framework/types" + + environmentsmodels "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/environments/models" + "github.com/cloudera/terraform-provider-cdp/utils" +) + +func ConvertFreeIpaInstances(freeIpaInstances []*environmentsmodels.FreeIpaInstance) *[]FreeIpaInstance { + var instances []FreeIpaInstance + if freeIpaInstances != nil || len(freeIpaInstances) > 0 { + instances = make([]FreeIpaInstance, 0) + for _, instance := range freeIpaInstances { + var attachedVolumes []*AttachedVolumeDetail + if instance.AttachedVolumes != nil { + attachedVolumes = make([]*AttachedVolumeDetail, 0) + for _, volume := range instance.AttachedVolumes { + attachedVolumes = append(attachedVolumes, &AttachedVolumeDetail{ + Count: utils.ConvertInt32ToTypesInt64(volume.Count), + Size: utils.ConvertInt32ToTypesInt64(volume.Size), + VolumeType: types.StringValue(volume.VolumeType), + }) + } + } + instances = append(instances, FreeIpaInstance{ + AttachedVolumes: attachedVolumes, + AvailabilityZone: types.StringValue(instance.AvailabilityZone), + DiscoveryFQDN: types.StringValue(instance.DiscoveryFQDN), + InstanceGroup: types.StringValue(instance.InstanceGroup), + InstanceID: types.StringValue(instance.InstanceID), + InstanceStatus: types.StringValue(instance.InstanceStatus), + InstanceStatusReason: types.StringValue(instance.InstanceStatusReason), + InstanceType: types.StringValue(instance.InstanceType), + InstanceVMType: types.StringValue(instance.InstanceVMType), + LifeCycle: types.StringValue(instance.LifeCycle), + PrivateIP: types.StringValue(instance.PrivateIP), + PublicIP: types.StringValue(instance.PublicIP), + SSHPort: utils.ConvertInt32ToTypesInt64(instance.SSHPort), + SubnetID: types.StringValue(instance.SubnetID), + }) + } + } + return &instances +} diff --git a/resources/environments/converter_common_test.go b/resources/environments/converter_common_test.go new file mode 100644 index 00000000..7e1df7ca --- /dev/null +++ b/resources/environments/converter_common_test.go @@ -0,0 +1,119 @@ +// Copyright 2023 Cloudera. All Rights Reserved. +// +// This file is licensed under the Apache License Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// +// This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. Refer to the License for the specific +// permissions and limitations governing your use of the file. + +package environments + +import ( + "github.com/stretchr/testify/assert" + "testing" + + environmentsmodels "github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/gen/environments/models" + "github.com/cloudera/terraform-provider-cdp/utils" +) + +func TestConvertFreeIpaInstancesWhenResultShouldBeEmpty(t *testing.T) { + tests := []struct { + name string + input []*environmentsmodels.FreeIpaInstance + }{ + {name: "test when input slice is nil", input: nil}, + {name: "test when input slice is empty", input: make([]*environmentsmodels.FreeIpaInstance, 0)}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := ConvertFreeIpaInstances(test.input) + assert.NotNil(t, result) + assert.Equal(t, 0, len(*result)) + }) + } +} + +func TestConvertFreeIpaInstancesForRootBasicComponents(t *testing.T) { + testElement := createTestFreeIpaInstanceOfEnvironmentmodels() + input := make([]*environmentsmodels.FreeIpaInstance, 0) + input = append(input, testElement) + + result := ConvertFreeIpaInstances(input) + + assert.Equal(t, testElement.PublicIP, (*result)[0].PublicIP.ValueString()) + assert.Equal(t, testElement.SubnetID, (*result)[0].SubnetID.ValueString()) + assert.Equal(t, testElement.LifeCycle, (*result)[0].LifeCycle.ValueString()) + assert.Equal(t, testElement.PrivateIP, (*result)[0].PrivateIP.ValueString()) + assert.Equal(t, testElement.InstanceID, (*result)[0].InstanceID.ValueString()) + assert.Equal(t, testElement.InstanceType, (*result)[0].InstanceType.ValueString()) + assert.Equal(t, testElement.DiscoveryFQDN, (*result)[0].DiscoveryFQDN.ValueString()) + assert.Equal(t, testElement.InstanceGroup, (*result)[0].InstanceGroup.ValueString()) + assert.Equal(t, testElement.InstanceStatus, (*result)[0].InstanceStatus.ValueString()) + assert.Equal(t, testElement.InstanceVMType, (*result)[0].InstanceVMType.ValueString()) + assert.Equal(t, testElement.InstanceStatusReason, (*result)[0].InstanceStatusReason.ValueString()) + assert.Equal(t, func(i int32) int64 { return int64(i) }(testElement.SSHPort), (*result)[0].SSHPort.ValueInt64()) +} + +func TestConvertFreeIpaInstancesForAttachedVolumesSize(t *testing.T) { + testElement := createTestFreeIpaInstanceOfEnvironmentmodels() + testElement.AttachedVolumes = append(testElement.AttachedVolumes, &environmentsmodels.AttachedVolumeDetail{ + Count: 4321, + Size: 4321, + VolumeType: "someOtherVolumeType", + }) + input := make([]*environmentsmodels.FreeIpaInstance, 0) + input = append(input, testElement) + + result := ConvertFreeIpaInstances(input) + + assert.Equal(t, len(testElement.AttachedVolumes), len((*result)[0].AttachedVolumes)) +} + +func TestConvertFreeIpaInstancesForAttachedVolumesContent(t *testing.T) { + testElement := createTestFreeIpaInstanceOfEnvironmentmodels() + input := make([]*environmentsmodels.FreeIpaInstance, 0) + input = append(input, testElement) + + result := ConvertFreeIpaInstances(input) + + assert.Equal(t, testElement.AttachedVolumes[0].VolumeType, (*result)[0].AttachedVolumes[0].VolumeType.ValueString()) + assert.Equal(t, utils.ConvertInt32ToTypesInt64(testElement.AttachedVolumes[0].Count), (*result)[0].AttachedVolumes[0].Count) + assert.Equal(t, utils.ConvertInt32ToTypesInt64(testElement.AttachedVolumes[0].Size), (*result)[0].AttachedVolumes[0].Size) +} + +func TestConvertFreeIpaInstancesIfThereAreMultipleInputsThenMultipleOutputShoutReturn(t *testing.T) { + input := make([]*environmentsmodels.FreeIpaInstance, 0) + input = append(input, createTestFreeIpaInstanceOfEnvironmentmodels()) + input = append(input, createTestFreeIpaInstanceOfEnvironmentmodels()) + + assert.Equal(t, len(input), len(*ConvertFreeIpaInstances(input))) +} + +func createTestFreeIpaInstanceOfEnvironmentmodels() *environmentsmodels.FreeIpaInstance { + return &environmentsmodels.FreeIpaInstance{ + AttachedVolumes: func(slc []*environmentsmodels.AttachedVolumeDetail) []*environmentsmodels.AttachedVolumeDetail { + vol := &environmentsmodels.AttachedVolumeDetail{ + Count: 1234, + Size: 1234, + VolumeType: "someVolumeType", + } + slc = append(slc, vol) + return slc + }(make([]*environmentsmodels.AttachedVolumeDetail, 0)), + AvailabilityZone: "someAvailabilityZone", + DiscoveryFQDN: "someDiscoveryFQDN", + InstanceGroup: "someInstanceGroup", + InstanceID: "someInstanceID", + InstanceStatus: "someInstanceStatus", + InstanceStatusReason: "someInstanceStatusReason", + InstanceType: "someInstanceType", + InstanceVMType: "someInstanceVMType", + LifeCycle: "someLifeCycle", + PrivateIP: "somePrivateIP", + PublicIP: "somePublicIP", + SSHPort: 1234, + SubnetID: "someSubnetID", + } +} diff --git a/resources/environments/converter_gcp.go b/resources/environments/converter_gcp.go index 3b00fc5a..5eaac9fd 100644 --- a/resources/environments/converter_gcp.go +++ b/resources/environments/converter_gcp.go @@ -120,4 +120,11 @@ func toGcpEnvironmentResource(ctx context.Context, env *environmentsmodels.Envir } model.EnableTunnel = types.BoolValue(env.TunnelEnabled) model.WorkloadAnalytics = types.BoolValue(env.WorkloadAnalytics) + if env.Freeipa != nil { + model.FreeIpa = &GcpFreeIpa{ + InstanceCountByGroup: utils.ConvertIntToTypesInt64(len(env.Freeipa.Instances)), + Recipes: utils.ConvertStringSliceToTypesSet(env.Freeipa.Recipes), + Instances: ConvertFreeIpaInstances(env.Freeipa.Instances), + } + } } diff --git a/resources/environments/model_common_environment.go b/resources/environments/model_common_environment.go new file mode 100644 index 00000000..06e17436 --- /dev/null +++ b/resources/environments/model_common_environment.go @@ -0,0 +1,36 @@ +// Copyright 2023 Cloudera. All Rights Reserved. +// +// This file is licensed under the Apache License Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. +// +// This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. Refer to the License for the specific +// permissions and limitations governing your use of the file. + +package environments + +import "github.com/hashicorp/terraform-plugin-framework/types" + +type FreeIpaInstance struct { + AttachedVolumes []*AttachedVolumeDetail `tfsdk:"attachedVolumes"` + AvailabilityZone types.String `tfsdk:"availabilityZone"` + DiscoveryFQDN types.String `tfsdk:"discoveryFQDN"` + InstanceGroup types.String `tfsdk:"instanceGroup"` + InstanceID types.String `tfsdk:"instanceId"` + InstanceStatus types.String `tfsdk:"instanceStatus"` + InstanceStatusReason types.String `tfsdk:"instanceStatusReason"` + InstanceType types.String `tfsdk:"instanceType"` + InstanceVMType types.String `tfsdk:"instanceVmType"` + LifeCycle types.String `tfsdk:"lifeCycle"` + PrivateIP types.String `tfsdk:"privateIP"` + PublicIP types.String `tfsdk:"publicIP"` + SSHPort types.Int64 `tfsdk:"sshPort"` + SubnetID types.String `tfsdk:"subnetId"` +} + +type AttachedVolumeDetail struct { + Count types.Int64 `tfsdk:"count"` + Size types.Int64 `tfsdk:"size"` + VolumeType types.String `tfsdk:"volumeType"` +} diff --git a/resources/environments/model_gcp_environment.go b/resources/environments/model_gcp_environment.go index b4c2eec2..cc4cd896 100644 --- a/resources/environments/model_gcp_environment.go +++ b/resources/environments/model_gcp_environment.go @@ -65,9 +65,10 @@ type gcpEnvironmentResourceModel struct { } type GcpFreeIpa struct { - InstanceCountByGroup types.Int64 `tfsdk:"instance_count_by_group"` - Recipes types.Set `tfsdk:"recipes"` - InstanceType types.String `tfsdk:"instance_type"` + InstanceCountByGroup types.Int64 `tfsdk:"instance_count_by_group"` + Recipes types.Set `tfsdk:"recipes"` + InstanceType types.String `tfsdk:"instance_type"` + Instances *[]FreeIpaInstance `tfsdk:"instances"` } type ExistingNetworkParams struct { diff --git a/utils/utils.go b/utils/utils.go index 3f97d0b4..a3aefe27 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -13,6 +13,7 @@ package utils import ( "context" "fmt" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-log/tflog" "time" @@ -128,3 +129,24 @@ func FromSetValueToStringList(tl types.Set) []string { } return res } + +func ConvertStringSliceToTypesSet(input []string) types.Set { + var elems []attr.Value + elems = make([]attr.Value, len(input)) + for _, str := range input { + elems = append(elems, types.StringValue(str)) + } + var set types.Set + set, _ = types.SetValue(types.StringType, elems) + return set +} + +func ConvertIntToTypesInt64(input int) types.Int64 { + upgraded := int64(input) + return types.Int64Value(upgraded) +} + +func ConvertInt32ToTypesInt64(input int32) types.Int64 { + upgraded := int64(input) + return types.Int64Value(upgraded) +}