diff --git a/proxmox/cluster/sdn/zones/client.go b/proxmox/cluster/sdn/zones/client.go new file mode 100644 index 00000000..1adb4c0f --- /dev/null +++ b/proxmox/cluster/sdn/zones/client.go @@ -0,0 +1,23 @@ +/* + * 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 zones + +import ( + "fmt" + + "github.com/bpg/terraform-provider-proxmox/proxmox/api" +) + +// Client is a client for accessing the Proxmox SDN Zones API. +type Client struct { + api.Client +} + +// ExpandPath returns the API path for SDN zones. +func (c *Client) ExpandPath(path string) string { + return fmt.Sprintf("cluster/sdn/zones/%s", path) +} diff --git a/proxmox/cluster/sdn/zones/doc.go b/proxmox/cluster/sdn/zones/doc.go new file mode 100644 index 00000000..4afeea94 --- /dev/null +++ b/proxmox/cluster/sdn/zones/doc.go @@ -0,0 +1,11 @@ +/* + * 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 `zones` provides types and structures for managing Proxmox VE Software Defined Network (SDN) zones. +// SDN zones are logical network segments that can be configured with different network types including +// VLAN, QinQ, VXLAN, and EVPN. This package contains the data structures used for creating, updating, +// and managing SDN zones through the Proxmox API. +package zones diff --git a/proxmox/cluster/sdn/zones/zones.go b/proxmox/cluster/sdn/zones/zones.go new file mode 100644 index 00000000..23fd19cc --- /dev/null +++ b/proxmox/cluster/sdn/zones/zones.go @@ -0,0 +1,82 @@ +/* + * 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 zones + +import ( + "context" + "fmt" + "net/http" + + "github.com/bpg/terraform-provider-proxmox/proxmox/api" +) + +// GetZone retrieves a single SDN zone by ID. +func (c *Client) GetZone(ctx context.Context, id string) (*ZoneData, error) { + resBody := &ZoneResponseBody{} + + err := c.DoRequest(ctx, http.MethodGet, c.ExpandPath(id), nil, resBody) + if err != nil { + return nil, fmt.Errorf("error reading SDN zone %s: %w", id, err) + } + + if resBody.Data == nil { + return nil, api.ErrNoDataObjectInResponse + } + + return resBody.Data, nil +} + +// GetZones lists all SDN zones. +func (c *Client) GetZones(ctx context.Context) ([]ZoneData, error) { + resBody := &ZonesResponseBody{} + + err := c.DoRequest(ctx, http.MethodGet, c.ExpandPath(""), nil, resBody) + if err != nil { + return nil, fmt.Errorf("error listing SDN zones: %w", err) + } + + if resBody.Data == nil { + return nil, api.ErrNoDataObjectInResponse + } + + return *resBody.Data, nil +} + +// CreateZone creates a new SDN zone. +func (c *Client) CreateZone(ctx context.Context, data *ZoneRequestData) error { + err := c.DoRequest(ctx, http.MethodPost, c.ExpandPath(""), data, nil) + if err != nil { + return fmt.Errorf("error creating SDN zone: %w", err) + } + + return nil +} + +// UpdateZone updates an existing SDN zone. +func (c *Client) UpdateZone(ctx context.Context, data *ZoneRequestData) error { + /* PVE API does not allow to pass "type" in PUT requests, this doesn't makes any sense + since other required params like port, server must still be there + while we could spawn another struct, let's just fix it silently */ + data.Type = nil + + err := c.DoRequest(ctx, http.MethodPut, c.ExpandPath(data.ID), data, nil) + if err != nil { + return fmt.Errorf("error updating SDN zone: %w", err) + } + + return nil +} + +// DeleteZone deletes an SDN zone by ID. +func (c *Client) DeleteZone(ctx context.Context, id string) error { + err := c.DoRequest(ctx, http.MethodDelete, c.ExpandPath(id), nil, nil) + if err != nil { + return fmt.Errorf("error deleting SDN zone: %w", err) + } + + return nil +} diff --git a/proxmox/cluster/sdn/zones/zones_types.go b/proxmox/cluster/sdn/zones/zones_types.go new file mode 100644 index 00000000..f463cd26 --- /dev/null +++ b/proxmox/cluster/sdn/zones/zones_types.go @@ -0,0 +1,54 @@ +/* + * 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 zones + +type ZoneData struct { + ID string `json:"zone,omitempty" url:"zone,omitempty"` + Type *string `json:"type,omitempty" url:"type,omitempty"` + IPAM *string `json:"ipam,omitempty" url:"ipam,omitempty"` + DNS *string `json:"dns,omitempty" url:"dns,omitempty"` + ReverseDNS *string `json:"reversedns,omitempty" url:"reversedns,omitempty"` + DNSZone *string `json:"dnszone,omitempty" url:"dnszone,omitempty"` + Nodes *string `json:"nodes,omitempty" url:"nodes,omitempty"` + MTU *int64 `json:"mtu,omitempty" url:"mtu,omitempty"` + + // VLAN. + Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"` + + // QinQ. + ServiceVLAN *int64 `json:"tag,omitempty" url:"tag,omitempty"` + ServiceVLANProtocol *string `json:"vlan-protocol,omitempty" url:"vlan-protocol,omitempty"` + + // VXLAN. + Peers *string `json:"peers,omitempty" url:"peers,omitempty"` + + // EVPN. + Controller *string `json:"controller,omitempty" url:"controller,omitempty"` + VRFVXLANID *int64 `json:"vrf-vxlan,omitempty" url:"vrf-vxlan,omitempty"` + ExitNodes *string `json:"exitnodes,omitempty" url:"exitnodes,omitempty"` + ExitNodesPrimary *string `json:"exitnodes-primary,omitempty" url:"exitnodes-primary,omitempty"` + ExitNodesLocalRouting *int64 `json:"exitnodes-local-routing,omitempty" url:"exitnodes-local-routing,omitempty"` + AdvertiseSubnets *int64 `json:"advertise-subnets,omitempty" url:"advertise-subnets,omitempty"` + DisableARPNDSuppression *int64 `json:"disable-arp-nd-suppression,omitempty" url:"disable-arp-nd-suppression,omitempty"` + RouteTargetImport *string `json:"rt-import,omitempty" url:"rt-import,omitempty"` +} + +// ZoneRequestData wraps a ZoneData struct with optional delete instructions. +type ZoneRequestData struct { + ZoneData + Delete []string `url:"delete,omitempty"` +} + +// ZoneResponseBody represents the response for a single zone. +type ZoneResponseBody struct { + Data *ZoneData `json:"data"` +} + +// ZonesResponseBody represents the response for a list of zones. +type ZonesResponseBody struct { + Data *[]ZoneData `json:"data"` +}