Skip to content

fix: missing vds info with r/cluster import #235

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 72 additions & 30 deletions internal/cluster/cluster_operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/vmware/terraform-provider-vcf/internal/api_client"
"github.com/vmware/vcf-sdk-go/vcf"

"github.com/vmware/terraform-provider-vcf/internal/api_client"
"github.com/vmware/terraform-provider-vcf/internal/datastores"
"github.com/vmware/terraform-provider-vcf/internal/network"
"github.com/vmware/terraform-provider-vcf/internal/resource_utils"
Expand Down Expand Up @@ -370,19 +370,19 @@ func FlattenCluster(ctx context.Context, clusterObj *vcf.Cluster, apiClient *vcf
result["is_default"] = clusterObj.IsDefault
result["is_stretched"] = clusterObj.IsStretched

if clusterObj.VdsSpecs != nil {
flattenedVdsSpecs := getFlattenedVdsSpecsForRefs(*clusterObj.VdsSpecs)
result["vds"] = flattenedVdsSpecs
flattenedVdsSpecs, err := getFlattenedVdsSpecsForRefs(ctx, *clusterObj.Id, apiClient)
if err != nil {
return nil, fmt.Errorf("failed to get flattened VDS specs: %w", err)
}
result["vds"] = flattenedVdsSpecs

if clusterObj.Hosts != nil {
flattenedHostSpecs, err := getFlattenedHostSpecsForRefs(ctx, *clusterObj.Hosts, apiClient)
if err != nil {
return nil, err
}
result["host"] = flattenedHostSpecs
flattenedHostSpecs, err := getFlattenedHostSpecsForRefs(ctx, *clusterObj.Hosts, apiClient)
if err != nil {
return nil, err
}

result["host"] = flattenedHostSpecs

return &result, nil
}

Expand All @@ -404,18 +404,17 @@ func ImportCluster(ctx context.Context, data *schema.ResourceData, apiClient *vc
_ = data.Set("primary_datastore_type", clusterObj.PrimaryDatastoreType)
_ = data.Set("is_default", clusterObj.IsDefault)
_ = data.Set("is_stretched", clusterObj.IsStretched)
if clusterObj.VdsSpecs != nil {
flattenedVdsSpecs := getFlattenedVdsSpecsForRefs(*clusterObj.VdsSpecs)
_ = data.Set("vds", flattenedVdsSpecs)
flattenedVdsSpecs, err := getFlattenedVdsSpecsForRefs(ctx, *clusterObj.Id, apiClient)
if err != nil {
return nil, err
}
_ = data.Set("vds", flattenedVdsSpecs)

if clusterObj.Hosts != nil {
flattenedHostSpecs, err := getFlattenedHostSpecsForRefs(ctx, *clusterObj.Hosts, apiClient)
if err != nil {
return nil, err
}
_ = data.Set("host", flattenedHostSpecs)
flattenedHostSpecs, err := getFlattenedHostSpecsForRefs(ctx, *clusterObj.Hosts, apiClient)
if err != nil {
return nil, err
}
_ = data.Set("host", flattenedHostSpecs)

// get all domains and find our cluster to set the "domain_id" attribute, because
// cluster API doesn't provide parent domain ID.
Expand Down Expand Up @@ -462,20 +461,63 @@ func getFlattenedHostSpecsForRefs(ctx context.Context, hostRefs []vcf.HostRefere
api_client.LogError(vcfErr)
return nil, errors.New(*vcfErr.Message)
}
flattenedHostSpecs = append(flattenedHostSpecs, *FlattenHost(*hostObj))
flattenedHostSpecs = append(flattenedHostSpecs, FlattenHost(*hostObj))
}
return flattenedHostSpecs, nil
}

func getFlattenedVdsSpecsForRefs(vdsSpecs []vcf.VdsSpec) []map[string]interface{} {
flattenedVdsSpecs := *new([]map[string]interface{})
// Since backend API returns objects in random order sort VDSSpec list to ensure
// import is reproducible
sort.SliceStable(vdsSpecs, func(i, j int) bool {
return vdsSpecs[i].Name < vdsSpecs[j].Name
})
for _, vdsSpec := range vdsSpecs {
flattenedVdsSpecs = append(flattenedVdsSpecs, network.FlattenVdsSpec(vdsSpec))
func getFlattenedVdsSpecsForRefs(ctx context.Context, clusterId string, apiClient *vcf.ClientWithResponses) ([]map[string]interface{}, error) {
res, err := apiClient.GetVdsesWithResponse(ctx, clusterId)
if err != nil {
return nil, err
}
return flattenedVdsSpecs

switcheObj, vcfErr := api_client.GetResponseAs[[]vcf.Vds](res)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switcheObj -> switchObj
seems like a typo

if vcfErr != nil {
api_client.LogError(vcfErr)
return nil, errors.New(*vcfErr.Message)
}

flattenedVdsSpecs := make([]map[string]interface{}, len(*switcheObj))
for i, vds := range *switcheObj {
portGroups := vds.PortGroups
portGroupSpecs := make([]vcf.PortgroupSpec, len(*portGroups))
for j, pg := range *portGroups {
portGroupSpecs[j] = vcf.PortgroupSpec{
Name: pg.Name,
TransportType: pg.TransportType,
ActiveUplinks: pg.ActiveUplinks,
}
}

niocBandwidthAllocations := vds.NiocBandwidthAllocations
niocSpecs := make([]vcf.NiocBandwidthAllocationSpec, len(*niocBandwidthAllocations))
for k, nioc := range *niocBandwidthAllocations {
niocType := ""
if nioc.Type != nil {
niocType = *nioc.Type
}

niocSpecs[k] = vcf.NiocBandwidthAllocationSpec{
Type: niocType,
NiocTrafficResourceAllocation: vcf.NiocTrafficResourceAllocation{
SharesInfo: &vcf.SharesInfo{
Shares: nioc.NiocTrafficResourceAllocation.SharesInfo.Shares,
Level: nioc.NiocTrafficResourceAllocation.SharesInfo.Level,
},
},
}
}

vdsSpec := vcf.VdsSpec{
Name: vds.Name,
IsUsedByNsxt: vds.IsUsedByNsxt,
PortGroupSpecs: &portGroupSpecs,
NiocBandwidthAllocationSpecs: &niocSpecs,
}

flattenedVdsSpecs[i] = network.FlattenVdsSpec(&vdsSpec)
}

return flattenedVdsSpecs, nil
}
39 changes: 33 additions & 6 deletions internal/cluster/host_spec_subresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,22 +82,49 @@ func HostSpecSchema() *schema.Resource {
Type: schema.TypeList,
Optional: true,
Description: "vmnic configuration for the ESXi host",
Elem: network.VMNicSchema(),
Elem: &schema.Resource{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

network.VMNicSchema has a different set of properties, this will result in a breaking change.
Why is it necessary to change the schema here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that network.VMNicSchema represents a VMkernel adapter and you are declaring and populating a schema for a physical network adapter

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of the physical NIC",
},
"mac_address": {
Type: schema.TypeString,
Required: true,
Description: "MAC address of the physical NIC",
},
},
},
},
},
}
}

func FlattenHost(host vcf.Host) *map[string]interface{} {
func FlattenHost(host vcf.Host) map[string]interface{} {
result := make(map[string]interface{})
result["id"] = host.Id
result["host_name"] = host.Fqdn
ipAddresses := *host.IpAddresses
if len(ipAddresses) > 0 {
result["ip_address"] = ipAddresses[0].IpAddress

if host.IpAddresses != nil {
ipAddresses := *host.IpAddresses
if len(ipAddresses) > 0 {
result["ip_address"] = ipAddresses[0].IpAddress
}
}

if host.PhysicalNics != nil {
var physicalNics []map[string]interface{}
for _, nic := range *host.PhysicalNics {
nicMap := make(map[string]interface{})
nicMap["name"] = nic.DeviceName
nicMap["mac_address"] = nic.MacAddress
physicalNics = append(physicalNics, nicMap)
}
result["vmnic"] = physicalNics
}

return &result
return result
}

func TryConvertToHostSpec(object map[string]interface{}) (*vcf.HostSpec, error) {
Expand Down
10 changes: 6 additions & 4 deletions internal/network/nioc_bandwidth_allocation_subresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,13 @@ func tryConvertToNiocBandwidthAllocationSpec(object map[string]interface{}) (*vc

func flattenNiocBandwidthAllocationSpec(spec vcf.NiocBandwidthAllocationSpec) map[string]interface{} {
result := make(map[string]interface{})

result["type"] = spec.Type
result["limit"] = *spec.NiocTrafficResourceAllocation.Limit
result["reservation"] = *spec.NiocTrafficResourceAllocation.Reservation
result["shares"] = spec.NiocTrafficResourceAllocation.SharesInfo.Shares
result["shares_level"] = spec.NiocTrafficResourceAllocation.SharesInfo.Level

if spec.NiocTrafficResourceAllocation.SharesInfo != nil {
result["shares"] = spec.NiocTrafficResourceAllocation.SharesInfo.Shares
result["shares_level"] = spec.NiocTrafficResourceAllocation.SharesInfo.Level
}

return result
}
31 changes: 19 additions & 12 deletions internal/network/vds_subresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils"
"github.com/vmware/vcf-sdk-go/vcf"

utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils"
validationutils "github.com/vmware/terraform-provider-vcf/internal/validation"
)

Expand Down Expand Up @@ -98,23 +98,30 @@ func TryConvertToVdsSpec(object map[string]interface{}) (*vcf.VdsSpec, error) {
return result, nil
}

func FlattenVdsSpec(vdsSpec vcf.VdsSpec) map[string]interface{} {
func FlattenVdsSpec(vdsSpec *vcf.VdsSpec) map[string]interface{} {
result := make(map[string]interface{})
if vdsSpec == nil {
return result
}
result["name"] = vdsSpec.Name
result["is_used_by_nsx"] = vdsSpec.IsUsedByNsxt
flattenedNiocBandwidthAllocationSpecs := *new([]map[string]interface{})
for _, niocBandwidthAllocationSpec := range *vdsSpec.NiocBandwidthAllocationSpecs {
flattenedNiocBandwidthAllocationSpecs = append(flattenedNiocBandwidthAllocationSpecs,
flattenNiocBandwidthAllocationSpec(niocBandwidthAllocationSpec))

if vdsSpec.NiocBandwidthAllocationSpecs != nil {
flattenedNiocBandwidthAllocationSpecs := make([]map[string]interface{}, 0, len(*vdsSpec.NiocBandwidthAllocationSpecs))
for _, niocBandwidthAllocationSpec := range *vdsSpec.NiocBandwidthAllocationSpecs {
flattenedSpec := flattenNiocBandwidthAllocationSpec(niocBandwidthAllocationSpec)
flattenedNiocBandwidthAllocationSpecs = append(flattenedNiocBandwidthAllocationSpecs, flattenedSpec)
}
result["nioc_bandwidth_allocations"] = flattenedNiocBandwidthAllocationSpecs
}
result["nioc_bandwidth_allocations"] = flattenedNiocBandwidthAllocationSpecs

flattenedPortgroupSpecs := *new([]map[string]interface{})
for _, portgroupSpec := range *vdsSpec.PortGroupSpecs {
flattenedPortgroupSpecs = append(flattenedPortgroupSpecs,
flattenPortgroupSpec(portgroupSpec))
if vdsSpec.PortGroupSpecs != nil {
flattenedPortgroupSpecs := make([]map[string]interface{}, 0, len(*vdsSpec.PortGroupSpecs))
for _, portgroupSpec := range *vdsSpec.PortGroupSpecs {
flattenedPortgroupSpecs = append(flattenedPortgroupSpecs, flattenPortgroupSpec(portgroupSpec))
}
result["portgroup"] = flattenedPortgroupSpecs
}
result["portgroup"] = flattenedPortgroupSpecs

return result
}
1 change: 1 addition & 0 deletions internal/provider/data_source_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func TestAccDataSourceVcfCluster(t *testing.T) {
resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "primary_datastore_type"),
resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "is_default"),
resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "is_stretched"),
resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "vds"),
resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.0.id"),
resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.0.host_name"),
resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.0.ip_address"),
Expand Down
4 changes: 4 additions & 0 deletions internal/provider/resource_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func TestAccResourceVcfClusterCreate(t *testing.T) {
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "primary_datastore_type"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "is_default"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "is_stretched"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "vds"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.0.id"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.1.id"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.2.id"),
Expand Down Expand Up @@ -116,6 +117,7 @@ func TestAccResourceVcfClusterFull(t *testing.T) {
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "primary_datastore_type"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "is_default"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "is_stretched"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "vds"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.0.id"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.1.id"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.2.id"),
Expand Down Expand Up @@ -151,6 +153,7 @@ func TestAccResourceVcfClusterFull(t *testing.T) {
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "primary_datastore_type"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "is_default"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "is_stretched"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "vds"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.0.id"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.1.id"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.2.id"),
Expand Down Expand Up @@ -180,6 +183,7 @@ func TestAccResourceVcfClusterFull(t *testing.T) {
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "primary_datastore_type"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "is_default"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "is_stretched"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "vds"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.0.id"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.1.id"),
resource.TestCheckResourceAttrSet("vcf_cluster.cluster1", "host.2.id"),
Expand Down
Loading