Skip to content

Commit 035664f

Browse files
committed
feat(primary_storage) add primary storage datasource query.
fix(virtual_router_instance) fix create virtual_reourter_instance resource description null state error
1 parent ca7e63b commit 035664f

File tree

11 files changed

+367
-20
lines changed

11 files changed

+367
-20
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
page_title: "zstack_primary_storages Data Source - terraform-provider-zstack"
3+
subcategory: ""
4+
description: |-
5+
List all primary storages, or query primary storages by exact name match, or query primary storages by name pattern fuzzy match.
6+
---
7+
8+
# zstack_primary_storages (Data Source)
9+
10+
List all primary storages, or query primary storages by exact name match, or query primary storages by name pattern fuzzy match.
11+
12+
## Example Usage
13+
14+
```terraform
15+
data "zstack_primary_storages" "primary_storages_test" {
16+
filter {
17+
name = "status"
18+
values = ["Connected"]
19+
}
20+
filter {
21+
name = "state"
22+
values = ["Enabled"]
23+
}
24+
filter {
25+
name = "total_capacity"
26+
values = ["7937400246271"]
27+
}
28+
}
29+
30+
output "zstack_primary_storages_test" {
31+
value = data.zstack_primary_storages.primary_storages_test
32+
}
33+
```
34+
35+
<!-- schema generated by tfplugindocs -->
36+
## Schema
37+
38+
### Optional
39+
40+
- `filter` (Block List) Filter resources based on any field in the schema. For example, to filter by status, use `name = "status"` and `values = ["Ready"]`. (see [below for nested schema](#nestedblock--filter))
41+
- `name` (String) Exact name for searching primary storage.
42+
- `name_pattern` (String) Pattern for fuzzy name search, similar to MySQL LIKE. Use % for multiple characters and _ for exactly one character.
43+
44+
### Read-Only
45+
46+
- `primary_storages` (Attributes List) List of primary storage entries (see [below for nested schema](#nestedatt--primary_storages))
47+
48+
<a id="nestedblock--filter"></a>
49+
### Nested Schema for `filter`
50+
51+
Required:
52+
53+
- `name` (String) Name of the field to filter by (e.g., status, state).
54+
- `values` (Set of String) Values to filter by. Multiple values will be treated as an OR condition.
55+
56+
57+
<a id="nestedatt--primary_storages"></a>
58+
### Nested Schema for `primary_storages`
59+
60+
Read-Only:
61+
62+
- `available_capacity` (Number) Available capacity of the primary storage in bytes
63+
- `available_physical_capacity` (Number) Available physical capacity of the primary storage in bytes
64+
- `name` (String) Name of the primary storage
65+
- `state` (String) State of the primary storage (Enabled or Disabled)
66+
- `status` (String) Readiness status of the primary storage
67+
- `system_used_capacity` (Number) System used capacity of the primary storage in bytes
68+
- `total_capacity` (Number) Total capacity of the primary storage in bytes
69+
- `total_physical_capacity` (Number) Total physical capacity of the primary storage in bytes
70+
- `uuid` (String) UUID identifier of the primary storage
71+
72+
73+

docs/data-sources/virtual_router_offers.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ output "zstack_offers" {
3737

3838
### Optional
3939

40-
- `filter` (Block List) Filter resources based on any field in the schema. For example, to filter by status, use `name = "status"` and `values = ["Ready"]`. (see [below for nested schema](#nestedblock--filter))
40+
- `filter` (Block List) Filter resources based on any field in the schema. For example, to filter by state, use `name = "state"` and `values = ["Enabled"]`. (see [below for nested schema](#nestedblock--filter))
4141
- `name` (String) Exact name for searching virtual router offer
4242
- `name_pattern` (String) Pattern for fuzzy name search, similar to MySQL LIKE. Use % for multiple characters and _ for exactly one character.
4343

@@ -50,7 +50,7 @@ output "zstack_offers" {
5050

5151
Required:
5252

53-
- `name` (String) Name of the field to filter by (e.g., status, state).
53+
- `name` (String) Name of the field to filter by (e.g., cpu_num, memory_size, state).
5454
- `values` (Set of String) Values to filter by. Multiple values will be treated as an OR condition.
5555

5656

docs/resources/virtual_router_instance.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ output "zstack_virtual_router_instance" {
3939
- `description` (String) An optional description of the virtual router instance. Provides additional context or purpose of this instance.
4040
- `host_uuid` (String) The UUID of the host where the virtual router instance will be deployed. Takes precedence over both 'zone_uuid' and 'cluster_uuid' if specified.
4141
- `primary_storage_uuid_for_rootvolume` (String) The UUID of the primary storage where the root volume of the virtual router instance will be created. Ensures the root volume is placed on the specified storage.
42-
- `resource_uuid` (String) The UUID of the resource. If specified, the instance will use this value as its identifier.
4342
- `state` (String) The current state of the virtual router instance. Possible values include 'Enabled', 'Disabled', etc.
4443
- `status` (String) The operational status of the virtual router instance. Indicates whether the instance is running, stopped, or in an error Status.
4544
- `zone_uuid` (String) The UUID of the zone where the virtual router instance will be deployed. Ensures the instance is placed within a specific zone.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
data "zstack_primary_storages" "primary_storages_test" {
2+
filter {
3+
name = "status"
4+
values = ["Connected"]
5+
}
6+
filter {
7+
name = "state"
8+
values = ["Enabled"]
9+
}
10+
filter {
11+
name = "total_capacity"
12+
values = ["7937400246271"]
13+
}
14+
}
15+
16+
output "zstack_primary_storages_test" {
17+
value = data.zstack_primary_storages.primary_storages_test
18+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}"
3+
subcategory: ""
4+
description: |-
5+
{{ .Description | plainmarkdown | trimspace | prefixlines " " }}
6+
---
7+
8+
# {{.Name}} ({{.Type}})
9+
10+
{{ .Description }}
11+
12+
## Example Usage
13+
14+
{{tffile "examples/data-sources/primary_storages/data-source.tf"}}
15+
16+
{{ .SchemaMarkdown }}
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
// Copyright (c) ZStack.io, Inc.
2+
3+
package provider
4+
5+
import (
6+
"context"
7+
"fmt"
8+
"terraform-provider-zstack/zstack/utils"
9+
10+
"github.com/hashicorp/terraform-plugin-framework/datasource"
11+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
12+
"github.com/hashicorp/terraform-plugin-framework/types"
13+
"zstack.io/zstack-sdk-go/pkg/client"
14+
"zstack.io/zstack-sdk-go/pkg/param"
15+
)
16+
17+
var (
18+
_ datasource.DataSource = &primaryStorageDataSource{}
19+
_ datasource.DataSourceWithConfigure = &primaryStorageDataSource{}
20+
)
21+
22+
func ZStackPrimaryStorageDataSource() datasource.DataSource {
23+
return &primaryStorageDataSource{}
24+
}
25+
26+
type primaryStorage struct {
27+
Name types.String `tfsdk:"name"`
28+
Uuid types.String `tfsdk:"uuid"`
29+
State types.String `tfsdk:"state"`
30+
Status types.String `tfsdk:"status"`
31+
TotalCapacity types.Int64 `tfsdk:"total_capacity"`
32+
AvailableCapacity types.Int64 `tfsdk:"available_capacity"`
33+
TotalPhysicalCapacity types.Int64 `tfsdk:"total_physical_capacity"`
34+
AvailablePhysicalCapacity types.Int64 `tfsdk:"available_physical_capacity"`
35+
SystemUsedCapacity types.Int64 `tfsdk:"system_used_capacity"`
36+
}
37+
38+
type primaryStorageDataSourceModel struct {
39+
Name types.String `tfsdk:"name"`
40+
NamePattern types.String `tfsdk:"name_pattern"`
41+
Filter []Filter `tfsdk:"filter"`
42+
PrimaryStorges []primaryStorage `tfsdk:"primary_storages"`
43+
}
44+
45+
type primaryStorageDataSource struct {
46+
client *client.ZSClient
47+
}
48+
49+
// Configure implements datasource.DataSourceWithConfigure.
50+
func (d *primaryStorageDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
51+
if req.ProviderData == nil {
52+
return
53+
}
54+
55+
client, ok := req.ProviderData.(*client.ZSClient)
56+
if !ok {
57+
resp.Diagnostics.AddError(
58+
"Unexpected Data Source Configure Type",
59+
fmt.Sprintf("Expected *client.ZSClient, got: %T. Please report this issue to the Provider developer. ", req.ProviderData),
60+
)
61+
62+
return
63+
}
64+
d.client = client
65+
}
66+
67+
// Metadata implements datasource.DataSourceWithConfigure.
68+
func (d *primaryStorageDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
69+
resp.TypeName = req.ProviderTypeName + "_primary_storages"
70+
}
71+
72+
// Read implements datasource.DataSourceWithConfigure.
73+
func (d *primaryStorageDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
74+
var state primaryStorageDataSourceModel
75+
diags := req.Config.Get(ctx, &state)
76+
resp.Diagnostics.Append(diags...)
77+
78+
if resp.Diagnostics.HasError() {
79+
return
80+
}
81+
82+
params := param.NewQueryParam()
83+
84+
if !state.Name.IsNull() {
85+
params.AddQ("name=" + state.Name.ValueString())
86+
} else if !state.NamePattern.IsNull() {
87+
params.AddQ("name~=" + state.NamePattern.ValueString())
88+
}
89+
90+
primaryStorages, err := d.client.QueryPrimaryStorage(params)
91+
if err != nil {
92+
resp.Diagnostics.AddError(
93+
"Unable to Read ZStack primary Storages",
94+
err.Error(),
95+
)
96+
return
97+
}
98+
99+
filters := make(map[string][]string)
100+
for _, filter := range state.Filter {
101+
values := make([]string, 0, len(filter.Values.Elements()))
102+
diags := filter.Values.ElementsAs(ctx, &values, false)
103+
resp.Diagnostics.Append(diags...)
104+
if resp.Diagnostics.HasError() {
105+
return
106+
}
107+
filters[filter.Name.ValueString()] = values
108+
}
109+
110+
filterPrimaryStorage, filterDiags := utils.FilterResource(ctx, primaryStorages, filters, "primary_storage")
111+
resp.Diagnostics.Append(filterDiags...)
112+
if resp.Diagnostics.HasError() {
113+
return
114+
}
115+
116+
for _, primarystorage := range filterPrimaryStorage {
117+
primaryStorageState := primaryStorage{
118+
TotalCapacity: types.Int64Value(primarystorage.TotalCapacity),
119+
State: types.StringValue(primarystorage.State),
120+
Status: types.StringValue(primarystorage.Status),
121+
Uuid: types.StringValue(primarystorage.UUID),
122+
AvailableCapacity: types.Int64Value(primarystorage.AvailableCapacity),
123+
Name: types.StringValue(primarystorage.Name),
124+
TotalPhysicalCapacity: types.Int64Value(primarystorage.TotalPhysicalCapacity),
125+
AvailablePhysicalCapacity: types.Int64Value(primarystorage.AvailablePhysicalCapacity),
126+
SystemUsedCapacity: types.Int64Value(primarystorage.SystemUsedCapacity),
127+
}
128+
129+
state.PrimaryStorges = append(state.PrimaryStorges, primaryStorageState)
130+
}
131+
132+
diags = resp.State.Set(ctx, &state)
133+
resp.Diagnostics.Append(diags...)
134+
if resp.Diagnostics.HasError() {
135+
return
136+
}
137+
138+
}
139+
140+
// Schema implements datasource.DataSourceWithConfigure.
141+
func (d *primaryStorageDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
142+
resp.Schema = schema.Schema{
143+
Description: "List all primary storages, or query primary storages by exact name match, or query primary storages by name pattern fuzzy match.",
144+
Attributes: map[string]schema.Attribute{
145+
"name": schema.StringAttribute{
146+
Description: "Exact name for searching primary storage.",
147+
Optional: true,
148+
},
149+
"name_pattern": schema.StringAttribute{
150+
Description: "Pattern for fuzzy name search, similar to MySQL LIKE. Use % for multiple characters and _ for exactly one character.",
151+
Optional: true,
152+
},
153+
"primary_storages": schema.ListNestedAttribute{
154+
Description: "List of primary storage entries",
155+
Computed: true,
156+
NestedObject: schema.NestedAttributeObject{
157+
Attributes: map[string]schema.Attribute{
158+
"name": schema.StringAttribute{
159+
Description: "Name of the primary storage",
160+
Computed: true,
161+
},
162+
163+
"uuid": schema.StringAttribute{
164+
Description: "UUID identifier of the primary storage",
165+
Computed: true,
166+
},
167+
"state": schema.StringAttribute{
168+
Description: "State of the primary storage (Enabled or Disabled)",
169+
Computed: true,
170+
},
171+
"status": schema.StringAttribute{
172+
Description: "Readiness status of the primary storage",
173+
Computed: true,
174+
},
175+
"total_capacity": schema.Int64Attribute{
176+
Description: "Total capacity of the primary storage in bytes",
177+
Computed: true,
178+
},
179+
"available_capacity": schema.Int64Attribute{
180+
Description: "Available capacity of the primary storage in bytes",
181+
Computed: true,
182+
},
183+
"total_physical_capacity": schema.Int64Attribute{
184+
Description: "Total physical capacity of the primary storage in bytes",
185+
Computed: true,
186+
},
187+
"available_physical_capacity": schema.Int64Attribute{
188+
Description: "Available physical capacity of the primary storage in bytes",
189+
Computed: true,
190+
},
191+
"system_used_capacity": schema.Int64Attribute{
192+
Description: "System used capacity of the primary storage in bytes",
193+
Computed: true,
194+
},
195+
},
196+
},
197+
},
198+
},
199+
Blocks: map[string]schema.Block{
200+
"filter": schema.ListNestedBlock{
201+
Description: "Filter resources based on any field in the schema. For example, to filter by status, use `name = \"status\"` and `values = [\"Ready\"]`.",
202+
NestedObject: schema.NestedBlockObject{
203+
Attributes: map[string]schema.Attribute{
204+
"name": schema.StringAttribute{
205+
Description: "Name of the field to filter by (e.g., status, state).",
206+
Required: true,
207+
},
208+
"values": schema.SetAttribute{
209+
Description: "Values to filter by. Multiple values will be treated as an OR condition.",
210+
Required: true,
211+
ElementType: types.StringType,
212+
},
213+
},
214+
},
215+
},
216+
},
217+
}
218+
}

zstack/provider/data_source_zstack_virtual_router_offers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,11 @@ func (d *vrouterOfferingDataSource) Schema(ctx context.Context, req datasource.S
248248
},
249249
Blocks: map[string]schema.Block{
250250
"filter": schema.ListNestedBlock{
251-
Description: "Filter resources based on any field in the schema. For example, to filter by status, use `name = \"status\"` and `values = [\"Ready\"]`.",
251+
Description: "Filter resources based on any field in the schema. For example, to filter by state, use `name = \"state\"` and `values = [\"Enabled\"]`.",
252252
NestedObject: schema.NestedBlockObject{
253253
Attributes: map[string]schema.Attribute{
254254
"name": schema.StringAttribute{
255-
Description: "Name of the field to filter by (e.g., status, state).",
255+
Description: "Name of the field to filter by (e.g., cpu_num, memory_size, state).",
256256
Required: true,
257257
},
258258
"values": schema.SetAttribute{

zstack/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ func (p *ZStackProvider) DataSources(ctx context.Context) []func() datasource.Da
297297
ZStackVIPsDataSource,
298298
ZStackInstanceOfferingDataSource,
299299
ZStackDiskOfferingDataSource,
300+
ZStackPrimaryStorageDataSource,
300301
}
301302

302303
}

0 commit comments

Comments
 (0)