diff --git a/docs/data-sources/domain.md b/docs/data-sources/domain.md index 1aabfe9..fee92c3 100644 --- a/docs/data-sources/domain.md +++ b/docs/data-sources/domain.md @@ -14,11 +14,11 @@ storage (vSAN/NFS/VMFS on FC/VVOL) and networking (NSX) into a single consumable ## Schema -### Required +### Optional - `domain_id` (String) The ID of the Domain to be used as data source - -### Optional + +- `name` (String) The Name of the Domain to be used as data source - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) diff --git a/examples/data-sources/domain/variables.tf b/examples/data-sources/domain/variables.tf index b2a8c03..22bf18e 100644 --- a/examples/data-sources/domain/variables.tf +++ b/examples/data-sources/domain/variables.tf @@ -1,19 +1,21 @@ +variable "sddc_manager_host" { + description = "The fully qualified domain name of the SDDC Manager instance." +} + variable "sddc_manager_username" { - description = "Username used to authenticate against an SDDC Manager instance" - default = "" + description = "The username to authenticate to the SDDC Manager instance." + sensitive = true } variable "sddc_manager_password" { - description = "Password used to authenticate against an SDDC Manager instance" - default = "" + description = "The password to authenticate to the SDDC Manager instance." + sensitive = true } -variable "sddc_manager_host" { - description = "Fully qualified domain name of an SDDC Manager instance" - default = "" +variable "domain_id" { + description = "The ID of the workload domain." } -variable "vcf_domain_id" { - description = "Id of the domain that is to be used as a data source. Note: management domain ID can be used to refer to some of it's attributes" - default = "" +variable "domain_name" { + description = "The name of the workload domain." } \ No newline at end of file diff --git a/examples/data-sources/domain/vcf_domain.tf b/examples/data-sources/domain/vcf_domain.tf index dce1620..6fe69da 100644 --- a/examples/data-sources/domain/vcf_domain.tf +++ b/examples/data-sources/domain/vcf_domain.tf @@ -12,6 +12,10 @@ provider "vcf" { sddc_manager_host = var.sddc_manager_host } -data "vcf_domain" "domain1" { - domain_id = var.vcf_domain_id +data "vcf_domain" "sfo-m01" { + domain_id = var.domain_id +} + +data "vcf_domain" "sfo-w01" { + name = var.domain_name } \ No newline at end of file diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 45c7a2b..1d83268 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -119,6 +119,10 @@ const ( // Typically, the id of management domain is used as it is already created during bringup. VcfTestDomainDataSourceId = "VCF_DOMAIN_DATA_SOURCE_ID" + // VcfTestDomainDataSourceName name of a workload domain used in workload domain data source acceptance test. + // Typically, the name of management domain is used as it is already created during bringup. + VcfTestDomainDataSourceName = "VCF_DOMAIN_DATA_SOURCE_NAME" + // VcfTestClusterDataSourceId id of cluster used in cluster data source acceptance test. // Typically, the id of the default cluster in the management domain is used as it is // already created during bringup. diff --git a/internal/provider/data_source_domain.go b/internal/provider/data_source_domain.go index ed788f6..987e2a5 100644 --- a/internal/provider/data_source_domain.go +++ b/internal/provider/data_source_domain.go @@ -6,13 +6,19 @@ package provider import ( "context" + "errors" + "fmt" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/vmware/vcf-sdk-go/client" + "github.com/vmware/vcf-sdk-go/client/domains" + "github.com/vmware/vcf-sdk-go/models" "github.com/vmware/terraform-provider-vcf/internal/api_client" + "github.com/vmware/terraform-provider-vcf/internal/constants" "github.com/vmware/terraform-provider-vcf/internal/domain" "github.com/vmware/terraform-provider-vcf/internal/network" "github.com/vmware/terraform-provider-vcf/internal/vcenter" @@ -27,13 +33,13 @@ func DataSourceDomain() *schema.Resource { Schema: map[string]*schema.Schema{ "domain_id": { Type: schema.TypeString, - Required: true, ValidateFunc: validation.NoZeroValues, + Optional: true, Description: "The ID of the Domain to be used as data source", }, "name": { Type: schema.TypeString, - Computed: true, + Optional: true, Description: "Name of the domain", }, "cluster": { @@ -84,13 +90,50 @@ func DataSourceDomain() *schema.Resource { } func dataSourceDomainRead(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { - vcfClient := meta.(*api_client.SddcManagerClient) - apiClient := vcfClient.ApiClient + apiClient := meta.(*api_client.SddcManagerClient).ApiClient + domainId := data.Get("domain_id").(string) + domainName := data.Get("name").(string) + + if domainId == "" { + if domainName == "" { + return diag.Errorf("either 'domain_id' or 'name' must be provided") + } + + domainInfo, err := getDomainByName(ctx, apiClient, domainName) + if err != nil { + return diag.FromErr(err) + } + domainId = domainInfo.ID + } _, err := domain.ImportDomain(ctx, data, apiClient, domainId, true) if err != nil { return diag.FromErr(err) } + return nil } + +func getDomainByName(ctx context.Context, apiClient *client.VcfClient, name string) (*models.Domain, error) { + params := domains.NewGetDomainsParamsWithContext(ctx). + WithTimeout(constants.DefaultVcfApiCallTimeout) + + domainsResponse, err := apiClient.Domains.GetDomains(params) + if err != nil { + return nil, err + } + + if domainsResponse.Payload == nil { + return nil, errors.New("no domains found") + } + + for _, domainElement := range domainsResponse.Payload.Elements { + domain := *domainElement + if domain.Name == name { + return &domain, nil + } + } + + return nil, fmt.Errorf("domain name '%s' not found", name) +} diff --git a/internal/provider/data_source_domain_test.go b/internal/provider/data_source_domain_test.go index 629fc4f..324dad9 100644 --- a/internal/provider/data_source_domain_test.go +++ b/internal/provider/data_source_domain_test.go @@ -14,46 +14,68 @@ import ( "github.com/vmware/terraform-provider-vcf/internal/constants" ) -func TestAccDataSourceVcfDomain(t *testing.T) { +func testAccVcfDomainDataSourceSteps(config string) []resource.TestStep { + return []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "vcenter_configuration.0.id"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "vcenter_configuration.0.fqdn"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "status"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "type"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "sso_id"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "sso_name"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.id"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.name"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.primary_datastore_name"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.primary_datastore_type"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.is_default"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.is_stretched"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.0.id"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.1.id"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.2.id"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.3.id"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.id"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.vip"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.vip_fqdn"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.nsx_manager_node.0.name"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.nsx_manager_node.0.ip_address"), + resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.nsx_manager_node.0.fqdn"), + ), + }, + } +} + +func testAccVcfDomainDataSourceConfigById(domainId string) string { + return fmt.Sprintf(` + data "vcf_domain" "domain1" { + domain_id = %q + }`, domainId) +} + +func testAccVcfDomainDataSourceConfigByName(name string) string { + return fmt.Sprintf(` + data "vcf_domain" "domain1" { + name = %q + }`, name) +} + +func TestAccDataSourceVcfDomainById(t *testing.T) { + config := testAccVcfDomainDataSourceConfigById(os.Getenv(constants.VcfTestDomainDataSourceId)) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProviderFactories: providerFactories, - Steps: []resource.TestStep{ - { - Config: testAccVcfDomainDataSourceConfig( - os.Getenv(constants.VcfTestDomainDataSourceId)), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "vcenter_configuration.0.id"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "vcenter_configuration.0.fqdn"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "status"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "type"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "sso_id"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "sso_name"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.id"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.name"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.primary_datastore_name"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.primary_datastore_type"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.is_default"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.is_stretched"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.0.id"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.1.id"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.2.id"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.3.id"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.id"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.vip"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.vip_fqdn"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.nsx_manager_node.0.name"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.nsx_manager_node.0.ip_address"), - resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.nsx_manager_node.0.fqdn"), - ), - }, - }, + Steps: testAccVcfDomainDataSourceSteps(config), }) } -func testAccVcfDomainDataSourceConfig(domainId string) string { - return fmt.Sprintf(` - data "vcf_domain" "domain1" { - domain_id = %q - }`, domainId) +func TestAccDataSourceVcfDomainByName(t *testing.T) { + config := testAccVcfDomainDataSourceConfigByName(os.Getenv(constants.VcfTestDomainDataSourceName)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: providerFactories, + Steps: testAccVcfDomainDataSourceSteps(config), + }) }