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 <ian.cro...@telus.com>
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.

Reply via email to