This is an automated email from the ASF dual-hosted git repository.
vishesh pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/cloudstack-terraform-provider.git
The following commit(s) were added to refs/heads/main by this push:
new 1216148 Add `cloudstack_domain` as a data source (#195)
1216148 is described below
commit 1216148e07ab0f97f132d487508269a3075eb2f4
Author: Ian <[email protected]>
AuthorDate: Mon Sep 8 05:13:44 2025 -0700
Add `cloudstack_domain` as a data source (#195)
---
cloudstack/data_source_cloudstack_domain.go | 133 +++++++++++++++++++++++
cloudstack/data_source_cloudstack_domain_test.go | 133 +++++++++++++++++++++++
cloudstack/provider.go | 1 +
website/docs/d/domain.html.markdown | 39 +++++++
4 files changed, 306 insertions(+)
diff --git a/cloudstack/data_source_cloudstack_domain.go
b/cloudstack/data_source_cloudstack_domain.go
new file mode 100644
index 0000000..324160c
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_domain.go
@@ -0,0 +1,133 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+ "fmt"
+ "log"
+
+ "github.com/apache/cloudstack-go/v2/cloudstack"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+func dataSourceCloudstackDomain() *schema.Resource {
+ return &schema.Resource{
+ Read: dataSourceCloudstackDomainRead,
+ Schema: map[string]*schema.Schema{
+ "filter": dataSourceFiltersSchema(),
+
+ // Computed values
+ "domain_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "network_domain": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "parent_domain_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ },
+ }
+}
+
+func dataSourceCloudstackDomainRead(d *schema.ResourceData, meta interface{})
error {
+ log.Printf("Domain Data Source Read Started")
+
+ cs := meta.(*cloudstack.CloudStackClient)
+ p := cs.Domain.NewListDomainsParams()
+
+ var filterName, filterValue string
+ var filterByName, filterByID bool
+
+ // Apply filters if provided
+ if filters, filtersOk := d.GetOk("filter"); filtersOk {
+ for _, f := range filters.(*schema.Set).List() {
+ m := f.(map[string]interface{})
+ name := m["name"].(string)
+ value := m["value"].(string)
+
+ switch name {
+ case "name":
+ p.SetName(value)
+ filterName = value
+ filterByName = true
+ log.Printf("[DEBUG] Filtering by name: %s",
value)
+ case "id":
+ p.SetId(value)
+ filterValue = value
+ filterByID = true
+ log.Printf("[DEBUG] Filtering by ID: %s", value)
+ }
+ }
+ }
+
+ csDomains, err := cs.Domain.ListDomains(p)
+ if err != nil {
+ return fmt.Errorf("failed to list domains: %s", err)
+ }
+
+ log.Printf("[DEBUG] Found %d domains from CloudStack API",
len(csDomains.Domains))
+
+ var domain *cloudstack.Domain
+
+ // If we have results from the API call, select the appropriate domain
+ if len(csDomains.Domains) > 0 {
+ // If we filtered by ID or name through the API, we should have
a specific result
+ if filterByID || filterByName {
+ // Since we used API filtering, the first result should
be our match
+ domain = csDomains.Domains[0]
+ log.Printf("[DEBUG] Using API-filtered domain: %s",
domain.Name)
+ } else {
+ // If no filters were applied, we need to handle this
case
+ // This shouldn't happen with the current schema as
filters are required
+ return fmt.Errorf("no filter criteria specified")
+ }
+ }
+
+ if domain == nil {
+ if filterByName {
+ return fmt.Errorf("no domain found with name: %s",
filterName)
+ } else if filterByID {
+ return fmt.Errorf("no domain found with ID: %s",
filterValue)
+ } else {
+ return fmt.Errorf("no domain found matching the
specified criteria")
+ }
+ }
+
+ log.Printf("[DEBUG] Selected domain: %s (ID: %s)", domain.Name,
domain.Id)
+
+ return domainDescriptionAttributes(d, domain)
+}
+
+func domainDescriptionAttributes(d *schema.ResourceData, domain
*cloudstack.Domain) error {
+ d.SetId(domain.Id)
+ d.Set("domain_id", domain.Id)
+ d.Set("name", domain.Name)
+ d.Set("network_domain", domain.Networkdomain)
+ d.Set("parent_domain_id", domain.Parentdomainid)
+
+ return nil
+}
diff --git a/cloudstack/data_source_cloudstack_domain_test.go
b/cloudstack/data_source_cloudstack_domain_test.go
new file mode 100644
index 0000000..3a6e98b
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_domain_test.go
@@ -0,0 +1,133 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+ "fmt"
+ "regexp"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+ "github.com/hashicorp/terraform-plugin-testing/terraform"
+)
+
+func TestAccCloudstackDomainDataSource_basic(t *testing.T) {
+ resourceName := "data.cloudstack_domain.my_domain"
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ Steps: []resource.TestStep{
+ {
+ Config:
testAccCloudstackDomainDataSource_basic(),
+ Check: resource.ComposeTestCheckFunc(
+
testAccCheckCloudstackDomainDataSourceExists(resourceName),
+
resource.TestCheckResourceAttr(resourceName, "name", "ROOT"),
+ ),
+ },
+ },
+ })
+}
+
+func testAccCheckCloudstackDomainDataSourceExists(n string)
resource.TestCheckFunc {
+ return func(s *terraform.State) error {
+ rs, ok := s.RootModule().Resources[n]
+ if !ok {
+ return fmt.Errorf("Not found: %s", n)
+ }
+
+ if rs.Primary.ID == "" {
+ return fmt.Errorf("No Domain ID is set")
+ }
+
+ return nil
+ }
+}
+
+func TestAccCloudstackDomainDataSource_invalidName(t *testing.T) {
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ Steps: []resource.TestStep{
+ {
+ Config:
testAccCloudstackDomainDataSource_invalidName(),
+ ExpectError: regexp.MustCompile("no domain
found with name: badgerbearocto"),
+ },
+ },
+ })
+}
+
+func testAccCloudstackDomainDataSource_basic() string {
+ return `
+data "cloudstack_domain" "my_domain" {
+ filter {
+ name = "name"
+ value = "ROOT"
+ }
+}
+`
+}
+
+func testAccCloudstackDomainDataSource_invalidName() string {
+ return `
+data "cloudstack_domain" "my_domain" {
+ filter {
+ name = "name"
+ value = "badgerbearocto"
+ }
+}
+`
+}
+
+func TestAccCloudstackDomainDataSource_byID(t *testing.T) {
+ domainResourceName := "cloudstack_domain.test_domain"
+ dataSourceName := "data.cloudstack_domain.my_domain_by_id"
+ testDomainName := "test-domain-" + id.UniqueId()
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ Steps: []resource.TestStep{
+ {
+ Config:
testAccCloudstackDomainDataSource_byID(testDomainName),
+ Check: resource.ComposeTestCheckFunc(
+
testAccCheckCloudstackDomainDataSourceExists(dataSourceName),
+
resource.TestCheckResourceAttrPair(dataSourceName, "name", domainResourceName,
"name"),
+
resource.TestCheckResourceAttrPair(dataSourceName, "domain_id",
domainResourceName, "id"),
+ ),
+ },
+ },
+ })
+}
+
+func testAccCloudstackDomainDataSource_byID(domainName string) string {
+ return fmt.Sprintf(`
+resource "cloudstack_domain" "test_domain" {
+ name = "%s"
+}
+
+data "cloudstack_domain" "my_domain_by_id" {
+ filter {
+ name = "id"
+ value = cloudstack_domain.test_domain.id
+ }
+}
+`, domainName)
+}
diff --git a/cloudstack/provider.go b/cloudstack/provider.go
index 877325e..fb4b1d6 100644
--- a/cloudstack/provider.go
+++ b/cloudstack/provider.go
@@ -90,6 +90,7 @@ func Provider() *schema.Provider {
"cloudstack_user":
dataSourceCloudstackUser(),
"cloudstack_vpn_connection":
dataSourceCloudstackVPNConnection(),
"cloudstack_pod":
dataSourceCloudstackPod(),
+ "cloudstack_domain":
dataSourceCloudstackDomain(),
"cloudstack_physicalnetwork":
dataSourceCloudStackPhysicalNetwork(),
},
diff --git a/website/docs/d/domain.html.markdown
b/website/docs/d/domain.html.markdown
new file mode 100644
index 0000000..d7318b0
--- /dev/null
+++ b/website/docs/d/domain.html.markdown
@@ -0,0 +1,39 @@
+---
+layout: default
+page_title: "CloudStack: cloudstack_domain Data Source"
+sidebar_current: "docs-cloudstack-datasource-domain"
+description: |-
+ Retrieves information about a Domain
+---
+
+# CloudStack: cloudstack_domain Data Source
+
+A `cloudstack_domain` data source retrieves information about a domain within
CloudStack.
+
+## Example Usage
+
+```hcl
+data "cloudstack_domain" "my_domain" {
+ filter {
+ name = "name"
+ value = "ROOT"
+ }
+}
+```
+
+## Argument Reference
+
+The following arguments are supported:
+
+* `filter` - (Required) A block to filter the domains. The filter block
supports the following:
+ * `name` - (Required) The name of the filter.
+ * `value` - (Required) The value of the filter.
+
+## Attributes Reference
+
+The following attributes are exported:
+
+* `id` - The ID of the domain.
+* `name` - The name of the domain.
+* `network_domain` - The network domain for the domain.
+* `parent_domain_id` - The ID of the parent domain.