Skip to content

Commit 96f287a

Browse files
authored
Add cloudstack_limits data source and resource (#197)
1 parent afa7a18 commit 96f287a

8 files changed

+1619
-3
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
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+
"bytes"
23+
"crypto/sha256"
24+
"encoding/hex"
25+
"fmt"
26+
27+
"github.com/apache/cloudstack-go/v2/cloudstack"
28+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
29+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
30+
)
31+
32+
func dataSourceCloudStackLimits() *schema.Resource {
33+
return &schema.Resource{
34+
Read: dataSourceCloudStackLimitsRead,
35+
Schema: map[string]*schema.Schema{
36+
"type": {
37+
Type: schema.TypeString,
38+
Optional: true,
39+
ValidateFunc: validation.StringInSlice([]string{
40+
"instance", "ip", "volume", "snapshot", "template", "project", "network", "vpc",
41+
"cpu", "memory", "primarystorage", "secondarystorage",
42+
}, false), // false disables case-insensitive matching
43+
Description: "The type of resource to list the limits. Available types are: " +
44+
"instance, ip, volume, snapshot, template, project, network, vpc, cpu, memory, " +
45+
"primarystorage, secondarystorage",
46+
},
47+
"account": {
48+
Type: schema.TypeString,
49+
Optional: true,
50+
Description: "List resources by account. Must be used with the domain_id parameter.",
51+
},
52+
"domain_id": {
53+
Type: schema.TypeString,
54+
Optional: true,
55+
Description: "List only resources belonging to the domain specified.",
56+
},
57+
"project": {
58+
Type: schema.TypeString,
59+
Optional: true,
60+
Description: "List resource limits by project.",
61+
},
62+
"limits": {
63+
Type: schema.TypeList,
64+
Computed: true,
65+
Elem: &schema.Resource{
66+
Schema: map[string]*schema.Schema{
67+
"resourcetype": {
68+
Type: schema.TypeString,
69+
Computed: true,
70+
},
71+
"resourcetypename": {
72+
Type: schema.TypeString,
73+
Computed: true,
74+
},
75+
"account": {
76+
Type: schema.TypeString,
77+
Computed: true,
78+
},
79+
"domain": {
80+
Type: schema.TypeString,
81+
Computed: true,
82+
},
83+
"domain_id": {
84+
Type: schema.TypeString,
85+
Computed: true,
86+
},
87+
"max": {
88+
Type: schema.TypeInt,
89+
Computed: true,
90+
},
91+
"project": {
92+
Type: schema.TypeString,
93+
Computed: true,
94+
},
95+
"projectid": {
96+
Type: schema.TypeString,
97+
Computed: true,
98+
},
99+
},
100+
},
101+
},
102+
},
103+
}
104+
}
105+
106+
func dataSourceCloudStackLimitsRead(d *schema.ResourceData, meta interface{}) error {
107+
cs := meta.(*cloudstack.CloudStackClient)
108+
109+
// Create a new parameter struct
110+
p := cs.Limit.NewListResourceLimitsParams()
111+
112+
// Set optional parameters
113+
if v, ok := d.GetOk("type"); ok {
114+
typeStr := v.(string)
115+
if resourcetype, ok := resourceTypeMap[typeStr]; ok {
116+
p.SetResourcetype(resourcetype)
117+
} else {
118+
return fmt.Errorf("invalid type value: %s", typeStr)
119+
}
120+
}
121+
122+
if v, ok := d.GetOk("account"); ok {
123+
p.SetAccount(v.(string))
124+
}
125+
126+
if v, ok := d.GetOk("domain_id"); ok {
127+
p.SetDomainid(v.(string))
128+
}
129+
130+
if v, ok := d.GetOk("project"); ok {
131+
p.SetProjectid(v.(string))
132+
}
133+
134+
// Retrieve the resource limits
135+
l, err := cs.Limit.ListResourceLimits(p)
136+
if err != nil {
137+
return fmt.Errorf("Error retrieving resource limits: %s", err)
138+
}
139+
140+
// Generate a unique ID for this data source
141+
id := generateDataSourceID(d)
142+
d.SetId(id)
143+
144+
limits := make([]map[string]interface{}, 0, len(l.ResourceLimits))
145+
146+
// Set the resource data
147+
for _, limit := range l.ResourceLimits {
148+
limitMap := map[string]interface{}{
149+
"resourcetype": limit.Resourcetype,
150+
"resourcetypename": limit.Resourcetypename,
151+
"max": limit.Max,
152+
}
153+
154+
if limit.Account != "" {
155+
limitMap["account"] = limit.Account
156+
}
157+
158+
if limit.Domain != "" {
159+
limitMap["domain"] = limit.Domain
160+
}
161+
162+
if limit.Domainid != "" {
163+
limitMap["domain_id"] = limit.Domainid
164+
}
165+
166+
if limit.Project != "" {
167+
limitMap["project"] = limit.Project
168+
}
169+
170+
if limit.Projectid != "" {
171+
limitMap["projectid"] = limit.Projectid
172+
}
173+
174+
limits = append(limits, limitMap)
175+
}
176+
177+
if err := d.Set("limits", limits); err != nil {
178+
return fmt.Errorf("Error setting limits: %s", err)
179+
}
180+
181+
return nil
182+
}
183+
184+
// generateDataSourceID generates a unique ID for the data source based on its parameters
185+
func generateDataSourceID(d *schema.ResourceData) string {
186+
var buf bytes.Buffer
187+
188+
if v, ok := d.GetOk("type"); ok {
189+
typeStr := v.(string)
190+
if resourcetype, ok := resourceTypeMap[typeStr]; ok {
191+
buf.WriteString(fmt.Sprintf("%d-", resourcetype))
192+
}
193+
}
194+
195+
if v, ok := d.GetOk("account"); ok {
196+
buf.WriteString(fmt.Sprintf("%s-", v.(string)))
197+
}
198+
199+
if v, ok := d.GetOk("domain_id"); ok {
200+
buf.WriteString(fmt.Sprintf("%s-", v.(string)))
201+
}
202+
203+
if v, ok := d.GetOk("project"); ok {
204+
buf.WriteString(fmt.Sprintf("%s-", v.(string)))
205+
}
206+
207+
// Generate a SHA-256 hash of the buffer content
208+
hash := sha256.Sum256(buf.Bytes())
209+
return fmt.Sprintf("limits-%s", hex.EncodeToString(hash[:])[:8])
210+
}

0 commit comments

Comments
 (0)