Skip to content

Commit d85ccb2

Browse files
authored
Merge pull request #57 from poddm/resource_configuration
Adding configuration resource
2 parents a653531 + 4795c95 commit d85ccb2

File tree

3 files changed

+341
-0
lines changed

3 files changed

+341
-0
lines changed

cloudstack/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ func Provider() *schema.Provider {
9696
"cloudstack_affinity_group": resourceCloudStackAffinityGroup(),
9797
"cloudstack_attach_volume": resourceCloudStackAttachVolume(),
9898
"cloudstack_autoscale_vm_profile": resourceCloudStackAutoScaleVMProfile(),
99+
"cloudstack_configuration": resourceCloudStackConfiguration(),
99100
"cloudstack_disk": resourceCloudStackDisk(),
100101
"cloudstack_egress_firewall": resourceCloudStackEgressFirewall(),
101102
"cloudstack_firewall": resourceCloudStackFirewall(),
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
20+
package cloudstack
21+
22+
import (
23+
"fmt"
24+
25+
"github.com/apache/cloudstack-go/v2/cloudstack"
26+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
27+
)
28+
29+
func resourceCloudStackConfiguration() *schema.Resource {
30+
return &schema.Resource{
31+
Create: resourceCloudStackConfigurationCreate,
32+
Read: resourceCloudStackConfigurationRead,
33+
Update: resourceCloudStackConfigurationUpdate,
34+
Delete: resourceCloudStackConfigurationDelete,
35+
Importer: &schema.ResourceImporter{
36+
State: importStatePassthrough,
37+
},
38+
39+
Schema: map[string]*schema.Schema{
40+
"name": {
41+
Description: "configuration by name",
42+
Type: schema.TypeString,
43+
Required: true,
44+
},
45+
"account_id": {
46+
Description: "the ID of the Account to update the parameter value for corresponding account",
47+
Type: schema.TypeString,
48+
Optional: true,
49+
},
50+
"cluster_id": {
51+
Description: "the ID of the Cluster to update the parameter value for corresponding cluster",
52+
Type: schema.TypeString,
53+
Optional: true,
54+
},
55+
"domain_id": {
56+
Description: "the ID of the Domain to update the parameter value for corresponding domain",
57+
Type: schema.TypeString,
58+
Optional: true,
59+
},
60+
"image_store_uuid": {
61+
Description: "the ID of the Image Store to update the parameter value for corresponding image store",
62+
Type: schema.TypeString,
63+
Optional: true,
64+
},
65+
"store_id": {
66+
Description: "the ID of the Storage pool to update the parameter value for corresponding storage pool",
67+
Type: schema.TypeString,
68+
Optional: true,
69+
},
70+
"value": {
71+
Description: "the value of the configuration",
72+
Type: schema.TypeString,
73+
Optional: true,
74+
},
75+
"zone_id": {
76+
Description: "the ID of the Zone to update the parameter value for corresponding zone",
77+
Type: schema.TypeString,
78+
Optional: true,
79+
},
80+
// computed
81+
"category": {
82+
Description: "configurations by category",
83+
Type: schema.TypeString,
84+
Computed: true,
85+
},
86+
"description": {
87+
Description: "the description of the configuration",
88+
Type: schema.TypeString,
89+
Computed: true,
90+
},
91+
"is_dynamic": {
92+
Description: "true if the configuration is dynamic",
93+
Type: schema.TypeBool,
94+
Computed: true,
95+
},
96+
"scope": {
97+
Description: "scope(zone/cluster/pool/account) of the parameter that needs to be updated",
98+
Type: schema.TypeString,
99+
Computed: true,
100+
},
101+
},
102+
}
103+
}
104+
105+
func resourceCloudStackConfigurationRead(d *schema.ResourceData, meta interface{}) error {
106+
cs := meta.(*cloudstack.CloudStackClient)
107+
p := cs.Configuration.NewListConfigurationsParams()
108+
109+
// required
110+
p.SetName(d.Id())
111+
112+
// optional
113+
if v, ok := d.GetOk("account_id"); ok {
114+
p.SetAccountid(v.(string))
115+
}
116+
if v, ok := d.GetOk("category"); ok {
117+
p.SetCategory(v.(string))
118+
}
119+
if v, ok := d.GetOk("cluster_id"); ok {
120+
p.SetClusterid(v.(string))
121+
}
122+
if v, ok := d.GetOk("domain_id"); ok {
123+
p.SetDomainid(v.(string))
124+
}
125+
if v, ok := d.GetOk("image_store_uuid"); ok {
126+
p.SetImagestoreuuid(v.(string))
127+
}
128+
if v, ok := d.GetOk("store_id"); ok {
129+
p.SetStorageid(v.(string))
130+
}
131+
if v, ok := d.GetOk("zone_id"); ok {
132+
p.SetZoneid(v.(string))
133+
}
134+
135+
cfg, err := cs.Configuration.ListConfigurations(p)
136+
if err != nil {
137+
return err
138+
}
139+
140+
found := false
141+
for _, v := range cfg.Configurations {
142+
if v.Name == d.Id() {
143+
d.Set("category", v.Category)
144+
d.Set("description", v.Description)
145+
d.Set("is_dynamic", v.Isdynamic)
146+
d.Set("name", v.Name)
147+
d.Set("value", v.Value)
148+
d.Set("scope", v.Scope)
149+
found = true
150+
}
151+
}
152+
153+
if !found {
154+
return fmt.Errorf("listConfiguration failed. no matching names found %s", d.Id())
155+
}
156+
157+
return nil
158+
159+
}
160+
161+
func resourceCloudStackConfigurationCreate(d *schema.ResourceData, meta interface{}) error {
162+
if v, ok := d.GetOk("name"); ok {
163+
d.SetId(v.(string))
164+
}
165+
166+
resourceCloudStackConfigurationUpdate(d, meta)
167+
168+
return nil
169+
170+
}
171+
172+
func resourceCloudStackConfigurationUpdate(d *schema.ResourceData, meta interface{}) error {
173+
cs := meta.(*cloudstack.CloudStackClient)
174+
p := cs.Configuration.NewUpdateConfigurationParams(d.Id())
175+
176+
// Optional
177+
if v, ok := d.GetOk("account_id"); ok {
178+
p.SetAccountid(v.(string))
179+
}
180+
if v, ok := d.GetOk("cluster_id"); ok {
181+
p.SetClusterid(v.(string))
182+
}
183+
if v, ok := d.GetOk("domain_id"); ok {
184+
p.SetDomainid(v.(string))
185+
}
186+
if v, ok := d.GetOk("image_store_uuid"); ok {
187+
p.SetImagestoreuuid(v.(string))
188+
}
189+
if v, ok := d.GetOk("store_id"); ok {
190+
p.SetStorageid(v.(string))
191+
}
192+
if v, ok := d.GetOk("value"); ok {
193+
p.SetValue(v.(string))
194+
}
195+
if v, ok := d.GetOk("zone_id"); ok {
196+
p.SetZoneid(v.(string))
197+
}
198+
199+
_, err := cs.Configuration.UpdateConfiguration(p)
200+
if err != nil {
201+
return err
202+
}
203+
204+
resourceCloudStackConfigurationRead(d, meta)
205+
206+
return nil
207+
}
208+
209+
func resourceCloudStackConfigurationDelete(d *schema.ResourceData, meta interface{}) error {
210+
cs := meta.(*cloudstack.CloudStackClient)
211+
p := cs.Configuration.NewResetConfigurationParams(d.Id())
212+
213+
// Optional
214+
if v, ok := d.GetOk("account_id"); ok {
215+
p.SetAccountid(v.(string))
216+
}
217+
if v, ok := d.GetOk("cluster_id"); ok {
218+
p.SetClusterid(v.(string))
219+
}
220+
if v, ok := d.GetOk("domain_id"); ok {
221+
p.SetDomainid(v.(string))
222+
}
223+
if v, ok := d.GetOk("image_store_uuid"); ok {
224+
p.SetImagestoreid(v.(string))
225+
}
226+
if v, ok := d.GetOk("store_id"); ok {
227+
p.SetStorageid(v.(string))
228+
}
229+
if v, ok := d.GetOk("zone_id"); ok {
230+
p.SetZoneid(v.(string))
231+
}
232+
233+
_, err := cs.Configuration.ResetConfiguration(p)
234+
if err != nil {
235+
return err
236+
}
237+
238+
return nil
239+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package cloudstack
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/apache/cloudstack-go/v2/cloudstack"
8+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
9+
"github.com/hashicorp/terraform-plugin-testing/terraform"
10+
)
11+
12+
func TestAccCloudStackConfiguration_basic(t *testing.T) {
13+
var configuration cloudstack.ListConfigurationsResponse
14+
15+
resource.Test(t, resource.TestCase{
16+
PreCheck: func() { testAccPreCheck(t) },
17+
Providers: testAccProviders,
18+
CheckDestroy: testAccCheckCloudStackConfigurationDestroy,
19+
Steps: []resource.TestStep{
20+
{
21+
Config: testAccResourceConfiguration(),
22+
Check: resource.ComposeTestCheckFunc(
23+
testAccCheckCloudStackConfigurationExists("cloudstack_configuration.test", &configuration),
24+
resource.TestCheckResourceAttr("cloudstack_configuration.test", "value", "test_host"),
25+
),
26+
},
27+
},
28+
})
29+
}
30+
31+
func TestAccCloudStackConfiguration_import(t *testing.T) {
32+
resource.Test(t, resource.TestCase{
33+
PreCheck: func() { testAccPreCheck(t) },
34+
Providers: testAccProviders,
35+
Steps: []resource.TestStep{
36+
{
37+
Config: testAccResourceConfiguration(),
38+
},
39+
40+
{
41+
ResourceName: "cloudstack_configuration.test",
42+
ImportState: true,
43+
ImportStateVerify: true,
44+
},
45+
},
46+
})
47+
}
48+
49+
func testAccCheckCloudStackConfigurationExists(n string, configuration *cloudstack.ListConfigurationsResponse) 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("configuration ID not set")
58+
}
59+
60+
cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
61+
p := cs.Configuration.NewListConfigurationsParams()
62+
p.SetName(rs.Primary.ID)
63+
64+
cfg, err := cs.Configuration.ListConfigurations(p)
65+
if err != nil {
66+
return err
67+
}
68+
69+
*configuration = *cfg
70+
71+
return nil
72+
}
73+
}
74+
75+
func testAccCheckCloudStackConfigurationAttributes(configuration *cloudstack.ListConfigurationsResponse) resource.TestCheckFunc {
76+
return func(s *terraform.State) error {
77+
for _, v := range configuration.Configurations {
78+
if v.Name == "host" {
79+
if v.Value != "test_host" {
80+
return fmt.Errorf("Bad value: %s", v.Value)
81+
}
82+
return nil
83+
}
84+
}
85+
return fmt.Errorf("Bad name: %s", "host")
86+
}
87+
}
88+
89+
func testAccCheckCloudStackConfigurationDestroy(s *terraform.State) error {
90+
return nil
91+
92+
}
93+
94+
func testAccResourceConfiguration() string {
95+
return fmt.Sprintf(`
96+
resource "cloudstack_configuration" "test" {
97+
name = "host"
98+
value = "test_host"
99+
}
100+
`)
101+
}

0 commit comments

Comments
 (0)