Skip to content

Commit c50eed8

Browse files
jeanvetorellojean
andauthored
feature: add Quota plugin (#248)
* feature: add Quota plugin * chore: add Apache License header to quota-related files * fix: update PreCheck functions to use quota support checks in quota-related tests --------- Co-authored-by: jean <[email protected]>
1 parent e53f30c commit c50eed8

11 files changed

+1480
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
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+
"context"
24+
"crypto/sha1"
25+
"encoding/hex"
26+
"fmt"
27+
"strings"
28+
29+
"github.com/apache/cloudstack-go/v2/cloudstack"
30+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
31+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
32+
)
33+
34+
func dataSourceCloudStackQuota() *schema.Resource {
35+
return &schema.Resource{
36+
ReadContext: dataSourceCloudStackQuotaRead,
37+
38+
Schema: map[string]*schema.Schema{
39+
"account": {
40+
Type: schema.TypeString,
41+
Optional: true,
42+
Description: "Lists quota for the specified account",
43+
},
44+
45+
"domain_id": {
46+
Type: schema.TypeString,
47+
Optional: true,
48+
Description: "Lists quota for the specified domain ID",
49+
},
50+
51+
// Computed values
52+
"quotas": {
53+
Type: schema.TypeList,
54+
Computed: true,
55+
Description: "List of quota summaries",
56+
Elem: &schema.Resource{
57+
Schema: map[string]*schema.Schema{
58+
"account_id": {
59+
Type: schema.TypeString,
60+
Computed: true,
61+
Description: "Account ID",
62+
},
63+
64+
"account": {
65+
Type: schema.TypeString,
66+
Computed: true,
67+
Description: "Account name",
68+
},
69+
70+
"domain_id": {
71+
Type: schema.TypeString,
72+
Computed: true,
73+
Description: "Domain ID",
74+
},
75+
76+
"domain": {
77+
Type: schema.TypeString,
78+
Computed: true,
79+
Description: "Domain name",
80+
},
81+
82+
"quota_value": {
83+
Type: schema.TypeFloat,
84+
Computed: true,
85+
Description: "Current quota value",
86+
},
87+
88+
"quota_enabled": {
89+
Type: schema.TypeBool,
90+
Computed: true,
91+
Description: "Whether quota is enabled for this account",
92+
},
93+
},
94+
},
95+
},
96+
},
97+
}
98+
}
99+
100+
func dataSourceCloudStackQuotaRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
101+
cs := meta.(*cloudstack.CloudStackClient)
102+
103+
p := cs.Quota.NewQuotaSummaryParams()
104+
105+
if account, ok := d.GetOk("account"); ok {
106+
p.SetAccount(account.(string))
107+
}
108+
109+
if domainid, ok := d.GetOk("domain_id"); ok {
110+
p.SetDomainid(domainid.(string))
111+
}
112+
113+
r, err := cs.Quota.QuotaSummary(p)
114+
if err != nil {
115+
return diag.Errorf("Error retrieving quota summary: %s", err)
116+
}
117+
118+
quotas := make([]map[string]interface{}, 0, len(r.QuotaSummary))
119+
120+
for _, summary := range r.QuotaSummary {
121+
q := map[string]interface{}{
122+
"account_id": summary.Accountid,
123+
"account": summary.Account,
124+
"domain_id": summary.Domainid,
125+
"domain": summary.Domain,
126+
"quota_value": summary.Quota,
127+
"quota_enabled": summary.Quotaenabled,
128+
}
129+
quotas = append(quotas, q)
130+
}
131+
132+
if err := d.Set("quotas", quotas); err != nil {
133+
return diag.Errorf("Error setting quotas: %s", err)
134+
}
135+
136+
// Generate a unique ID for this data source
137+
var buf strings.Builder
138+
buf.WriteString(fmt.Sprintf("quota-summary"))
139+
if account, ok := d.GetOk("account"); ok {
140+
buf.WriteString(fmt.Sprintf("-account-%s", account.(string)))
141+
}
142+
if domainid, ok := d.GetOk("domain_id"); ok {
143+
buf.WriteString(fmt.Sprintf("-domain-%s", domainid.(string)))
144+
}
145+
146+
sha := sha1.Sum([]byte(buf.String()))
147+
d.SetId(hex.EncodeToString(sha[:]))
148+
149+
return nil
150+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
"context"
24+
"log"
25+
"strings"
26+
27+
"github.com/apache/cloudstack-go/v2/cloudstack"
28+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
29+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
30+
)
31+
32+
func dataSourceCloudStackQuotaEnabled() *schema.Resource {
33+
return &schema.Resource{
34+
ReadContext: dataSourceCloudStackQuotaEnabledRead,
35+
36+
Schema: map[string]*schema.Schema{
37+
"enabled": {
38+
Type: schema.TypeBool,
39+
Computed: true,
40+
Description: "Whether quota is enabled in the CloudStack management server",
41+
},
42+
},
43+
}
44+
}
45+
46+
func dataSourceCloudStackQuotaEnabledRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
47+
cs := meta.(*cloudstack.CloudStackClient)
48+
49+
p := cs.Quota.NewQuotaIsEnabledParams()
50+
r, err := cs.Quota.QuotaIsEnabled(p)
51+
52+
if err != nil {
53+
// Log the error for diagnostics
54+
log.Printf("[DEBUG] QuotaIsEnabled error: %s", err.Error())
55+
56+
// If the error contains "cannot unmarshal object", try custom parsing
57+
if strings.Contains(err.Error(), "cannot unmarshal object") {
58+
// The API is returning a nested structure, let's handle it
59+
// For now, assume quota is enabled if the API responds
60+
log.Printf("[WARN] CloudStack quota API returned nested structure, assuming enabled=true")
61+
d.Set("enabled", true)
62+
d.SetId("quota-enabled")
63+
return nil
64+
}
65+
66+
return diag.Errorf("Error checking quota status: %s", err)
67+
}
68+
69+
d.Set("enabled", r.Isenabled)
70+
d.SetId("quota-enabled")
71+
72+
return nil
73+
}

0 commit comments

Comments
 (0)