mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-08-22 19:38:35 +00:00
283 lines
10 KiB
Go
283 lines
10 KiB
Go
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
package zone
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
|
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/config"
|
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
|
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster/sdn/zones"
|
|
)
|
|
|
|
// Ensure the implementation satisfies the required interfaces.
|
|
var (
|
|
_ datasource.DataSource = &zonesDataSource{}
|
|
_ datasource.DataSourceWithConfigure = &zonesDataSource{}
|
|
)
|
|
|
|
// zonesDataSource is the data source implementation for SDN zones.
|
|
type zonesDataSource struct {
|
|
client *zones.Client
|
|
}
|
|
|
|
// zonesDataSourceModel represents the data source model for listing zones.
|
|
type zonesDataSourceModel struct {
|
|
Type types.String `tfsdk:"type"`
|
|
Zones types.List `tfsdk:"zones"`
|
|
}
|
|
|
|
// zoneDataModel represents individual zone data in the list.
|
|
type zoneDataModel struct {
|
|
ID types.String `tfsdk:"id"`
|
|
Type types.String `tfsdk:"type"`
|
|
IPAM types.String `tfsdk:"ipam"`
|
|
DNS types.String `tfsdk:"dns"`
|
|
ReverseDNS types.String `tfsdk:"reverse_dns"`
|
|
DNSZone types.String `tfsdk:"dns_zone"`
|
|
Nodes stringset.Value `tfsdk:"nodes"`
|
|
MTU types.Int64 `tfsdk:"mtu"`
|
|
Bridge types.String `tfsdk:"bridge"`
|
|
ServiceVLAN types.Int64 `tfsdk:"service_vlan"`
|
|
ServiceVLANProtocol types.String `tfsdk:"service_vlan_protocol"`
|
|
Peers stringset.Value `tfsdk:"peers"`
|
|
AdvertiseSubnets types.Bool `tfsdk:"advertise_subnets"`
|
|
Controller types.String `tfsdk:"controller"`
|
|
DisableARPNDSuppression types.Bool `tfsdk:"disable_arp_nd_suppression"`
|
|
ExitNodes stringset.Value `tfsdk:"exit_nodes"`
|
|
ExitNodesLocalRouting types.Bool `tfsdk:"exit_nodes_local_routing"`
|
|
PrimaryExitNode types.String `tfsdk:"primary_exit_node"`
|
|
RouteTargetImport types.String `tfsdk:"rt_import"`
|
|
VRFVXLANID types.Int64 `tfsdk:"vrf_vxlan"`
|
|
}
|
|
|
|
// Configure adds the provider-configured client to the data source.
|
|
func (d *zonesDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
|
if req.ProviderData == nil {
|
|
return
|
|
}
|
|
|
|
cfg, ok := req.ProviderData.(config.DataSource)
|
|
if !ok {
|
|
resp.Diagnostics.AddError(
|
|
"Unexpected DataSource Configure Type",
|
|
fmt.Sprintf("Expected config.DataSource, got: %T", req.ProviderData),
|
|
)
|
|
|
|
return
|
|
}
|
|
|
|
d.client = cfg.Client.Cluster().SDNZones()
|
|
}
|
|
|
|
// Metadata returns the data source type name.
|
|
func (d *zonesDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
|
|
resp.TypeName = req.ProviderTypeName + "_sdn_zones"
|
|
}
|
|
|
|
// Schema defines the schema for the data source.
|
|
func (d *zonesDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
|
resp.Schema = schema.Schema{
|
|
Description: "Retrieves information about all SDN Zones in Proxmox.",
|
|
MarkdownDescription: "Retrieves information about all SDN Zones in Proxmox. " +
|
|
"This data source can optionally filter zones by type.",
|
|
Attributes: map[string]schema.Attribute{
|
|
"type": schema.StringAttribute{
|
|
Description: "Filter zones by type (simple, vlan, qinq, vxlan, evpn).",
|
|
Optional: true,
|
|
Validators: []validator.String{
|
|
stringvalidator.OneOf("simple", "vlan", "qinq", "vxlan", "evpn"),
|
|
},
|
|
},
|
|
"zones": schema.ListAttribute{
|
|
Description: "List of SDN zones.",
|
|
Computed: true,
|
|
ElementType: types.ObjectType{
|
|
AttrTypes: map[string]attr.Type{
|
|
"id": types.StringType,
|
|
"type": types.StringType,
|
|
"ipam": types.StringType,
|
|
"dns": types.StringType,
|
|
"reverse_dns": types.StringType,
|
|
"dns_zone": types.StringType,
|
|
"nodes": types.SetType{
|
|
ElemType: types.StringType,
|
|
},
|
|
"mtu": types.Int64Type,
|
|
"bridge": types.StringType,
|
|
"service_vlan": types.Int64Type,
|
|
"service_vlan_protocol": types.StringType,
|
|
"peers": types.SetType{
|
|
ElemType: types.StringType,
|
|
},
|
|
"advertise_subnets": types.BoolType,
|
|
"controller": types.StringType,
|
|
"disable_arp_nd_suppression": types.BoolType,
|
|
"exit_nodes": types.SetType{
|
|
ElemType: types.StringType,
|
|
},
|
|
"exit_nodes_local_routing": types.BoolType,
|
|
"primary_exit_node": types.StringType,
|
|
"rt_import": types.StringType,
|
|
"vrf_vxlan": types.Int64Type,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// Read fetches all SDN zones from the Proxmox VE API.
|
|
func (d *zonesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
|
var data zonesDataSourceModel
|
|
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
|
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
zonesList, err := d.client.GetZones(ctx)
|
|
if err != nil {
|
|
resp.Diagnostics.AddError(
|
|
"Unable to Read SDN Zones",
|
|
err.Error(),
|
|
)
|
|
|
|
return
|
|
}
|
|
|
|
filteredZones := zonesList
|
|
|
|
if !data.Type.IsNull() && !data.Type.IsUnknown() {
|
|
filterType := data.Type.ValueString()
|
|
filteredZones = make([]zones.ZoneData, 0)
|
|
|
|
for _, zone := range zonesList {
|
|
if zone.Type != nil && *zone.Type == filterType {
|
|
filteredZones = append(filteredZones, zone)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Convert zones to list elements
|
|
zoneElements := make([]attr.Value, len(filteredZones))
|
|
for i, zone := range filteredZones {
|
|
diags := &resp.Diagnostics
|
|
|
|
zoneData := zoneDataModel{
|
|
ID: types.StringValue(zone.ID),
|
|
Type: types.StringPointerValue(zone.Type),
|
|
IPAM: types.StringPointerValue(zone.IPAM),
|
|
DNS: types.StringPointerValue(zone.DNS),
|
|
ReverseDNS: types.StringPointerValue(zone.ReverseDNS),
|
|
DNSZone: types.StringPointerValue(zone.DNSZone),
|
|
Nodes: stringset.NewValueString(zone.Nodes, diags, stringset.WithSeparator(",")),
|
|
MTU: types.Int64PointerValue(zone.MTU),
|
|
Bridge: types.StringPointerValue(zone.Bridge),
|
|
ServiceVLAN: types.Int64PointerValue(zone.ServiceVLAN),
|
|
ServiceVLANProtocol: types.StringPointerValue(zone.ServiceVLANProtocol),
|
|
Peers: stringset.NewValueString(zone.Peers, diags, stringset.WithSeparator(",")),
|
|
AdvertiseSubnets: types.BoolPointerValue(zone.AdvertiseSubnets.PointerBool()),
|
|
Controller: types.StringPointerValue(zone.Controller),
|
|
DisableARPNDSuppression: types.BoolPointerValue(zone.DisableARPNDSuppression.PointerBool()),
|
|
ExitNodes: stringset.NewValueString(zone.ExitNodes, diags, stringset.WithSeparator(",")),
|
|
ExitNodesLocalRouting: types.BoolPointerValue(zone.ExitNodesLocalRouting.PointerBool()),
|
|
PrimaryExitNode: types.StringPointerValue(zone.ExitNodesPrimary),
|
|
RouteTargetImport: types.StringPointerValue(zone.RouteTargetImport),
|
|
VRFVXLANID: types.Int64PointerValue(zone.VRFVXLANID),
|
|
}
|
|
|
|
objValue, objDiag := types.ObjectValueFrom(ctx, map[string]attr.Type{
|
|
"id": types.StringType,
|
|
"type": types.StringType,
|
|
"ipam": types.StringType,
|
|
"dns": types.StringType,
|
|
"reverse_dns": types.StringType,
|
|
"dns_zone": types.StringType,
|
|
"nodes": types.SetType{
|
|
ElemType: types.StringType,
|
|
},
|
|
"mtu": types.Int64Type,
|
|
"bridge": types.StringType,
|
|
"service_vlan": types.Int64Type,
|
|
"service_vlan_protocol": types.StringType,
|
|
"peers": types.SetType{
|
|
ElemType: types.StringType,
|
|
},
|
|
"advertise_subnets": types.BoolType,
|
|
"controller": types.StringType,
|
|
"disable_arp_nd_suppression": types.BoolType,
|
|
"exit_nodes": types.SetType{
|
|
ElemType: types.StringType,
|
|
},
|
|
"exit_nodes_local_routing": types.BoolType,
|
|
"primary_exit_node": types.StringType,
|
|
"rt_import": types.StringType,
|
|
"vrf_vxlan": types.Int64Type,
|
|
}, zoneData)
|
|
resp.Diagnostics.Append(objDiag...)
|
|
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
zoneElements[i] = objValue
|
|
}
|
|
|
|
listValue, listDiag := types.ListValue(types.ObjectType{
|
|
AttrTypes: map[string]attr.Type{
|
|
"id": types.StringType,
|
|
"type": types.StringType,
|
|
"ipam": types.StringType,
|
|
"dns": types.StringType,
|
|
"reverse_dns": types.StringType,
|
|
"dns_zone": types.StringType,
|
|
"nodes": types.SetType{
|
|
ElemType: types.StringType,
|
|
},
|
|
"mtu": types.Int64Type,
|
|
"bridge": types.StringType,
|
|
"service_vlan": types.Int64Type,
|
|
"service_vlan_protocol": types.StringType,
|
|
"peers": types.SetType{
|
|
ElemType: types.StringType,
|
|
},
|
|
"advertise_subnets": types.BoolType,
|
|
"controller": types.StringType,
|
|
"disable_arp_nd_suppression": types.BoolType,
|
|
"exit_nodes": types.SetType{
|
|
ElemType: types.StringType,
|
|
},
|
|
"exit_nodes_local_routing": types.BoolType,
|
|
"primary_exit_node": types.StringType,
|
|
"rt_import": types.StringType,
|
|
"vrf_vxlan": types.Int64Type,
|
|
},
|
|
}, zoneElements)
|
|
resp.Diagnostics.Append(listDiag...)
|
|
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
data.Zones = listValue
|
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
|
}
|
|
|
|
// NewZonesDataSource returns a new data source for SDN zones.
|
|
func NewZonesDataSource() datasource.DataSource {
|
|
return &zonesDataSource{}
|
|
}
|