Skip to content

Commit 9258f6c

Browse files
committed
Merge branch 'main' into feature/pods-and-clusters
2 parents 1082f61 + 6fbf6ff commit 9258f6c

File tree

55 files changed

+4122
-92
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+4122
-92
lines changed

.asf.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
118
github:
219
description: "CloudStack Terraform Provider"
320
homepage: https://cloudstack.apache.org

.github/workflows/acceptance.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ jobs:
9797
id: setup-cloudstack
9898
with:
9999
cloudstack-version: ${{ matrix.cloudstack-version }}
100-
- uses: opentofu/setup-opentofu@v1
100+
- uses: opentofu/setup-opentofu@000eeb8522f0572907c393e8151076c205fdba1b # v1.0.6
101101
with:
102102
tofu_version: ${{ matrix.opentofu-version }}
103103
- name: Run acceptance test

.github/workflows/rat.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: RAT Check
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- '**'
10+
11+
jobs:
12+
rat:
13+
name: Apache RAT Check
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
20+
- name: Set up Java
21+
uses: actions/setup-java@v4
22+
with:
23+
distribution: temurin
24+
java-version: 17
25+
26+
- name: Download Apache RAT
27+
run: |
28+
curl -L -O https://downloads.apache.org/creadur/apache-rat-0.16.1/apache-rat-0.16.1-bin.tar.gz
29+
tar -xzf apache-rat-0.16.1-bin.tar.gz
30+
31+
- name: Run RAT
32+
run: |
33+
java -jar apache-rat-0.16.1/apache-rat-0.16.1.jar -d . -E .rat-excludes > rat-report.txt
34+
cat rat-report.txt
35+
# Fail if unapproved licenses are found
36+
grep -qe '^0 Unknown Licenses' rat-report.txt && exit 0 || exit 1

.rat-excludes

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CHANGELOG.md
2+
CONTRIBUTING.md
3+
go.sum
4+
rat-report.txt
5+
apache-rat-0.16.1
6+
.gitignore
7+
.rat-excludes
8+
.terraform-registry
9+
website

GNUmakefile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
118
TEST?=$$(go list ./... | grep -v 'vendor')
219
GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor)
320
WEBSITE_REPO=github.com/hashicorp/terraform-website

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,13 @@ docker pull apache/cloudstack-simulator
128128

129129
or pull it with a particular build tag
130130

131-
docker pull apache/cloudstack-simulator:4.19.0.0
131+
docker pull apache/cloudstack-simulator:4.20.1.0
132132

133133
docker run --name simulator -p 8080:5050 -d apache/cloudstack-simulator
134134

135135
or
136136

137-
docker run --name simulator -p 8080:5050 -d apache/cloudstack-simulator:4.19.0.0
137+
docker run --name simulator -p 8080:5050 -d apache/cloudstack-simulator:4.20.1.0
138138
```
139139

140140
When Docker started the container you can go to http://localhost:8080/client and login to the CloudStack UI as user `admin` with password `password`. It can take a few minutes for the container is fully ready, so you probably need to wait and refresh the page for a few minutes before the login page is shown.
@@ -159,6 +159,12 @@ In order for all the tests to pass, you will need to create a new (empty) projec
159159
$ make testacc
160160
```
161161

162+
To execute specific test:
163+
164+
```sh
165+
$ make testacc TESTARGS='-run ^TestAccCloudStackNetworkACLRule_update$'
166+
```
167+
162168
## Sample Terraform configuration when testing locally
163169

164170
Below is an example configuration to initialize provider and create a Virtual Machine instance
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
//
18+
19+
package cloudstack
20+
21+
import (
22+
"fmt"
23+
"log"
24+
25+
"github.com/apache/cloudstack-go/v2/cloudstack"
26+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
27+
)
28+
29+
func dataSourceCloudstackDomain() *schema.Resource {
30+
return &schema.Resource{
31+
Read: dataSourceCloudstackDomainRead,
32+
Schema: map[string]*schema.Schema{
33+
"filter": dataSourceFiltersSchema(),
34+
35+
// Computed values
36+
"domain_id": {
37+
Type: schema.TypeString,
38+
Computed: true,
39+
},
40+
"name": {
41+
Type: schema.TypeString,
42+
Computed: true,
43+
},
44+
"network_domain": {
45+
Type: schema.TypeString,
46+
Computed: true,
47+
},
48+
"parent_domain_id": {
49+
Type: schema.TypeString,
50+
Computed: true,
51+
},
52+
},
53+
}
54+
}
55+
56+
func dataSourceCloudstackDomainRead(d *schema.ResourceData, meta interface{}) error {
57+
log.Printf("Domain Data Source Read Started")
58+
59+
cs := meta.(*cloudstack.CloudStackClient)
60+
p := cs.Domain.NewListDomainsParams()
61+
62+
var filterName, filterValue string
63+
var filterByName, filterByID bool
64+
65+
// Apply filters if provided
66+
if filters, filtersOk := d.GetOk("filter"); filtersOk {
67+
for _, f := range filters.(*schema.Set).List() {
68+
m := f.(map[string]interface{})
69+
name := m["name"].(string)
70+
value := m["value"].(string)
71+
72+
switch name {
73+
case "name":
74+
p.SetName(value)
75+
filterName = value
76+
filterByName = true
77+
log.Printf("[DEBUG] Filtering by name: %s", value)
78+
case "id":
79+
p.SetId(value)
80+
filterValue = value
81+
filterByID = true
82+
log.Printf("[DEBUG] Filtering by ID: %s", value)
83+
}
84+
}
85+
}
86+
87+
csDomains, err := cs.Domain.ListDomains(p)
88+
if err != nil {
89+
return fmt.Errorf("failed to list domains: %s", err)
90+
}
91+
92+
log.Printf("[DEBUG] Found %d domains from CloudStack API", len(csDomains.Domains))
93+
94+
var domain *cloudstack.Domain
95+
96+
// If we have results from the API call, select the appropriate domain
97+
if len(csDomains.Domains) > 0 {
98+
// If we filtered by ID or name through the API, we should have a specific result
99+
if filterByID || filterByName {
100+
// Since we used API filtering, the first result should be our match
101+
domain = csDomains.Domains[0]
102+
log.Printf("[DEBUG] Using API-filtered domain: %s", domain.Name)
103+
} else {
104+
// If no filters were applied, we need to handle this case
105+
// This shouldn't happen with the current schema as filters are required
106+
return fmt.Errorf("no filter criteria specified")
107+
}
108+
}
109+
110+
if domain == nil {
111+
if filterByName {
112+
return fmt.Errorf("no domain found with name: %s", filterName)
113+
} else if filterByID {
114+
return fmt.Errorf("no domain found with ID: %s", filterValue)
115+
} else {
116+
return fmt.Errorf("no domain found matching the specified criteria")
117+
}
118+
}
119+
120+
log.Printf("[DEBUG] Selected domain: %s (ID: %s)", domain.Name, domain.Id)
121+
122+
return domainDescriptionAttributes(d, domain)
123+
}
124+
125+
func domainDescriptionAttributes(d *schema.ResourceData, domain *cloudstack.Domain) error {
126+
d.SetId(domain.Id)
127+
d.Set("domain_id", domain.Id)
128+
d.Set("name", domain.Name)
129+
d.Set("network_domain", domain.Networkdomain)
130+
d.Set("parent_domain_id", domain.Parentdomainid)
131+
132+
return nil
133+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
//
18+
19+
package cloudstack
20+
21+
import (
22+
"fmt"
23+
"regexp"
24+
"testing"
25+
26+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
27+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
28+
"github.com/hashicorp/terraform-plugin-testing/terraform"
29+
)
30+
31+
func TestAccCloudstackDomainDataSource_basic(t *testing.T) {
32+
resourceName := "data.cloudstack_domain.my_domain"
33+
34+
resource.Test(t, resource.TestCase{
35+
PreCheck: func() { testAccPreCheck(t) },
36+
Providers: testAccProviders,
37+
Steps: []resource.TestStep{
38+
{
39+
Config: testAccCloudstackDomainDataSource_basic(),
40+
Check: resource.ComposeTestCheckFunc(
41+
testAccCheckCloudstackDomainDataSourceExists(resourceName),
42+
resource.TestCheckResourceAttr(resourceName, "name", "ROOT"),
43+
),
44+
},
45+
},
46+
})
47+
}
48+
49+
func testAccCheckCloudstackDomainDataSourceExists(n string) resource.TestCheckFunc {
50+
return func(s *terraform.State) error {
51+
rs, ok := s.RootModule().Resources[n]
52+
if !ok {
53+
return fmt.Errorf("Not found: %s", n)
54+
}
55+
56+
if rs.Primary.ID == "" {
57+
return fmt.Errorf("No Domain ID is set")
58+
}
59+
60+
return nil
61+
}
62+
}
63+
64+
func TestAccCloudstackDomainDataSource_invalidName(t *testing.T) {
65+
resource.Test(t, resource.TestCase{
66+
PreCheck: func() { testAccPreCheck(t) },
67+
Providers: testAccProviders,
68+
Steps: []resource.TestStep{
69+
{
70+
Config: testAccCloudstackDomainDataSource_invalidName(),
71+
ExpectError: regexp.MustCompile("no domain found with name: badgerbearocto"),
72+
},
73+
},
74+
})
75+
}
76+
77+
func testAccCloudstackDomainDataSource_basic() string {
78+
return `
79+
data "cloudstack_domain" "my_domain" {
80+
filter {
81+
name = "name"
82+
value = "ROOT"
83+
}
84+
}
85+
`
86+
}
87+
88+
func testAccCloudstackDomainDataSource_invalidName() string {
89+
return `
90+
data "cloudstack_domain" "my_domain" {
91+
filter {
92+
name = "name"
93+
value = "badgerbearocto"
94+
}
95+
}
96+
`
97+
}
98+
99+
func TestAccCloudstackDomainDataSource_byID(t *testing.T) {
100+
domainResourceName := "cloudstack_domain.test_domain"
101+
dataSourceName := "data.cloudstack_domain.my_domain_by_id"
102+
testDomainName := "test-domain-" + id.UniqueId()
103+
104+
resource.Test(t, resource.TestCase{
105+
PreCheck: func() { testAccPreCheck(t) },
106+
Providers: testAccProviders,
107+
Steps: []resource.TestStep{
108+
{
109+
Config: testAccCloudstackDomainDataSource_byID(testDomainName),
110+
Check: resource.ComposeTestCheckFunc(
111+
testAccCheckCloudstackDomainDataSourceExists(dataSourceName),
112+
resource.TestCheckResourceAttrPair(dataSourceName, "name", domainResourceName, "name"),
113+
resource.TestCheckResourceAttrPair(dataSourceName, "domain_id", domainResourceName, "id"),
114+
),
115+
},
116+
},
117+
})
118+
}
119+
120+
func testAccCloudstackDomainDataSource_byID(domainName string) string {
121+
return fmt.Sprintf(`
122+
resource "cloudstack_domain" "test_domain" {
123+
name = "%s"
124+
}
125+
126+
data "cloudstack_domain" "my_domain_by_id" {
127+
filter {
128+
name = "id"
129+
value = cloudstack_domain.test_domain.id
130+
}
131+
}
132+
`, domainName)
133+
}

0 commit comments

Comments
 (0)