Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/data-sources/virtual_environment_sdn_zone_evpn.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ output "data_proxmox_virtual_environment_sdn_zone_evpn" {
- `ipam` (String) IP Address Management system.
- `mtu` (Number) MTU value for the zone.
- `nodes` (Set of String) The Proxmox nodes which the zone and associated VNets are deployed on
- `pending` (Boolean) Indicates if the zone has pending configuration changes that need to be applied.
- `primary_exit_node` (String) Primary exit node for EVPN.
- `reverse_dns` (String) Reverse DNS API server address.
- `rt_import` (String) Route target import for EVPN. Must be in the format '<ASN>:<number>' (e.g., '65000:65000').
- `state` (String) Indicates the current state of the zone.
- `vrf_vxlan` (Number) VRF VXLAN-ID used for dedicated routing interconnect between VNets. It must be different than the VXLAN-ID of the VNets.
2 changes: 2 additions & 0 deletions docs/data-sources/virtual_environment_sdn_zone_qinq.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ output "data_proxmox_virtual_environment_sdn_zone_qinq" {
- `ipam` (String) IP Address Management system.
- `mtu` (Number) MTU value for the zone.
- `nodes` (Set of String) The Proxmox nodes which the zone and associated VNets are deployed on
- `pending` (Boolean) Indicates if the zone has pending configuration changes that need to be applied.
- `reverse_dns` (String) Reverse DNS API server address.
- `service_vlan` (Number) Service VLAN tag for QinQ. The tag must be between `1` and `4094`.
- `service_vlan_protocol` (String) Service VLAN protocol for QinQ. The protocol must be `802.1ad` or `802.1q`.
- `state` (String) Indicates the current state of the zone.
2 changes: 2 additions & 0 deletions docs/data-sources/virtual_environment_sdn_zone_simple.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ output "data_proxmox_virtual_environment_sdn_zone_simple" {
- `ipam` (String) IP Address Management system.
- `mtu` (Number) MTU value for the zone.
- `nodes` (Set of String) The Proxmox nodes which the zone and associated VNets are deployed on
- `pending` (Boolean) Indicates if the zone has pending configuration changes that need to be applied.
- `reverse_dns` (String) Reverse DNS API server address.
- `state` (String) Indicates the current state of the zone.
2 changes: 2 additions & 0 deletions docs/data-sources/virtual_environment_sdn_zone_vlan.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,6 @@ output "data_proxmox_virtual_environment_sdn_zone_vlan" {
- `ipam` (String) IP Address Management system.
- `mtu` (Number) MTU value for the zone.
- `nodes` (Set of String) The Proxmox nodes which the zone and associated VNets are deployed on
- `pending` (Boolean) Indicates if the zone has pending configuration changes that need to be applied.
- `reverse_dns` (String) Reverse DNS API server address.
- `state` (String) Indicates the current state of the zone.
2 changes: 2 additions & 0 deletions docs/data-sources/virtual_environment_sdn_zone_vxlan.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,6 @@ output "data_proxmox_virtual_environment_sdn_zone_vxlan" {
- `mtu` (Number) MTU value for the zone.
- `nodes` (Set of String) The Proxmox nodes which the zone and associated VNets are deployed on
- `peers` (Set of String) A list of IP addresses of each node in the VXLAN zone. This can be external nodes reachable at this IP address. All nodes in the cluster need to be mentioned here
- `pending` (Boolean) Indicates if the zone has pending configuration changes that need to be applied.
- `reverse_dns` (String) Reverse DNS API server address.
- `state` (String) Indicates the current state of the zone.
2 changes: 2 additions & 0 deletions docs/data-sources/virtual_environment_sdn_zones.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,12 @@ Read-Only:
- `mtu` (Number)
- `nodes` (Set of String)
- `peers` (Set of String)
- `pending` (Boolean)
- `primary_exit_node` (String)
- `reverse_dns` (String)
- `rt_import` (String)
- `service_vlan` (Number)
- `service_vlan_protocol` (String)
- `state` (String)
- `type` (String)
- `vrf_vxlan` (Number)
60 changes: 60 additions & 0 deletions docs/resources/virtual_environment_sdn_applier.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
layout: page
title: proxmox_virtual_environment_sdn_applier
parent: Resources
subcategory: Virtual Environment
description: |-
EXPERIMENTAL Triggers Proxmox's SDN Apply (equivalent to PUT /cluster/sdn).Intended to be used with replace_triggered_by so it runs after SDN objects change.
---

# Resource: proxmox_virtual_environment_sdn_applier

**EXPERIMENTAL** Triggers Proxmox's SDN **Apply** (equivalent to `PUT /cluster/sdn`).Intended to be used with `replace_triggered_by` so it runs after SDN objects change.

## Example Usage

```terraform
resource "proxmox_virtual_environment_sdn_zone_simple" "test_zone_1" {
id = "tZone1"
nodes = [data.proxmox_virtual_environment_nodes.example.names]
mtu = 1496

depends_on = [
proxmox_virtual_environment_sdn_applier.finalizer
]
}

resource "proxmox_virtual_environment_sdn_zone_simple" "test_zone_2" {
id = "tZone2"
nodes = [data.proxmox_virtual_environment_nodes.example.names]
mtu = 1496

depends_on = [
proxmox_virtual_environment_sdn_applier.finalizer
]
}

resource "proxmox_virtual_environment_sdn_applier" "applier" {
lifecycle {
replace_triggered_by = [
proxmox_virtual_environment_sdn_zone_simple.test_zone_1,
proxmox_virtual_environment_sdn_zone_simple.test_zone_2,
]
}

depends_on = [
proxmox_virtual_environment_sdn_zone_simple.test_zone_1,
proxmox_virtual_environment_sdn_zone_simple.test_zone_2,
]
}

resource "proxmox_virtual_environment_sdn_applier" "finalizer" {
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Read-Only

- `id` (String) Opaque identifier set to the Unix timestamp (milliseconds) when the apply was executed.
5 changes: 5 additions & 0 deletions docs/resources/virtual_environment_sdn_zone_evpn.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ resource "proxmox_virtual_environment_sdn_zone_evpn" "example" {
- `reverse_dns` (String) Reverse DNS API server address.
- `rt_import` (String) Route target import for EVPN.

### Read-Only

- `pending` (Boolean) Indicates if the zone has pending configuration changes that need to be applied.
- `state` (String) Indicates the current state of the zone.

## Import

Import is supported using the following syntax:
Expand Down
5 changes: 5 additions & 0 deletions docs/resources/virtual_environment_sdn_zone_qinq.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ resource "proxmox_virtual_environment_sdn_zone_qinq" "example" {
- `reverse_dns` (String) Reverse DNS API server address.
- `service_vlan_protocol` (String) Service VLAN protocol for QinQ. The protocol must be `802.1ad` or `802.1q`.

### Read-Only

- `pending` (Boolean) Indicates if the zone has pending configuration changes that need to be applied.
- `state` (String) Indicates the current state of the zone.

## Import

Import is supported using the following syntax:
Expand Down
5 changes: 5 additions & 0 deletions docs/resources/virtual_environment_sdn_zone_simple.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ resource "proxmox_virtual_environment_sdn_zone_simple" "example" {
- `mtu` (Number) MTU value for the zone.
- `reverse_dns` (String) Reverse DNS API server address.

### Read-Only

- `pending` (Boolean) Indicates if the zone has pending configuration changes that need to be applied.
- `state` (String) Indicates the current state of the zone.

## Import

Import is supported using the following syntax:
Expand Down
5 changes: 5 additions & 0 deletions docs/resources/virtual_environment_sdn_zone_vlan.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ resource "proxmox_virtual_environment_sdn_zone_vlan" "example" {
- `mtu` (Number) MTU value for the zone.
- `reverse_dns` (String) Reverse DNS API server address.

### Read-Only

- `pending` (Boolean) Indicates if the zone has pending configuration changes that need to be applied.
- `state` (String) Indicates the current state of the zone.

## Import

Import is supported using the following syntax:
Expand Down
5 changes: 5 additions & 0 deletions docs/resources/virtual_environment_sdn_zone_vxlan.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ resource "proxmox_virtual_environment_sdn_zone_vxlan" "example" {
- `mtu` (Number) MTU value for the zone.
- `reverse_dns` (String) Reverse DNS API server address.

### Read-Only

- `pending` (Boolean) Indicates if the zone has pending configuration changes that need to be applied.
- `state` (String) Indicates the current state of the zone.

## Import

Import is supported using the following syntax:
Expand Down
25 changes: 25 additions & 0 deletions example/resource_virtual_environment_sdn_applier.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
resource "proxmox_virtual_environment_sdn_zone_simple" "test_zone_1" {
id = "tZone1"
nodes= [data.proxmox_virtual_environment_nodes.example.names]
mtu = 1496
}

resource "proxmox_virtual_environment_sdn_zone_simple" "test_zone_2" {
id = "tZone2"
nodes= [data.proxmox_virtual_environment_nodes.example.names]
mtu = 1496
}

resource "proxmox_virtual_environment_sdn_applier" "apply" {
lifecycle {
replace_triggered_by = [
proxmox_virtual_environment_sdn_zone_simple.test_zone_1,
proxmox_virtual_environment_sdn_zone_simple.test_zone_2,
]
}

depends_on = [
proxmox_virtual_environment_sdn_zone_simple.test_zone_1,
proxmox_virtual_environment_sdn_zone_simple.test_zone_2,
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
resource "proxmox_virtual_environment_sdn_zone_simple" "test_zone_1" {
id = "tZone1"
nodes = [data.proxmox_virtual_environment_nodes.example.names]
mtu = 1496

depends_on = [
proxmox_virtual_environment_sdn_applier.finalizer
]
}

resource "proxmox_virtual_environment_sdn_zone_simple" "test_zone_2" {
id = "tZone2"
nodes = [data.proxmox_virtual_environment_nodes.example.names]
mtu = 1496

depends_on = [
proxmox_virtual_environment_sdn_applier.finalizer
]
}

resource "proxmox_virtual_environment_sdn_applier" "applier" {
lifecycle {
replace_triggered_by = [
proxmox_virtual_environment_sdn_zone_simple.test_zone_1,
proxmox_virtual_environment_sdn_zone_simple.test_zone_2,
]
}

depends_on = [
proxmox_virtual_environment_sdn_zone_simple.test_zone_1,
proxmox_virtual_environment_sdn_zone_simple.test_zone_2,
]
}

resource "proxmox_virtual_environment_sdn_applier" "finalizer" {
}
116 changes: 116 additions & 0 deletions fwprovider/cluster/sdn/applier/resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* 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 applier

import (
"context"
"fmt"
"strconv"
"time"

"github.com/bpg/terraform-provider-proxmox/fwprovider/config"
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster/sdn/applier"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var (
_ resource.Resource = &Resource{}
_ resource.ResourceWithConfigure = &Resource{}
)

type model struct {
// Opaque ID set timestamp at creation time.
ID types.String `tfsdk:"id"`
}

type Resource struct {
client *applier.Client
}

func NewResource() resource.Resource {
return &Resource{}
}

func (r *Resource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_sdn_applier"
}

func (r *Resource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: "Applies pending Proxmox SDN configuration (cluster-wide).",
MarkdownDescription: "**EXPERIMENTAL** Triggers Proxmox's SDN **Apply** (equivalent to `PUT /cluster/sdn`)." +
"Intended to be used with `replace_triggered_by` so it runs after SDN objects change.",
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
Description: "Opaque identifier set to the Unix timestamp (milliseconds) when the apply was executed.",
},
},
}
}

func (r *Resource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

cfg, ok := req.ProviderData.(config.Resource)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Resource Configure Type",
fmt.Sprintf("Expected config.Resource, got: %T", req.ProviderData),
)

return
}

r.client = cfg.Client.Cluster().SDNApplier()
}

func (r *Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
if err := r.client.ApplyConfig(ctx); err != nil {
resp.Diagnostics.AddError("Unable to Apply SDN Configuration", err.Error())
return
}

state := &model{
ID: types.StringValue(strconv.FormatInt(time.Now().UTC().UnixMilli(), 10)),
}
resp.Diagnostics.Append(resp.State.Set(ctx, state)...)
}

func (r *Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
// Nothing to refresh
}

func (r *Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
// We expect replacements only. But if someone does in-place Update,
// we just re-run apply for safety and bump the ID timestamp.
if err := r.client.ApplyConfig(ctx); err != nil {
resp.Diagnostics.AddError("Unable to Re-Apply SDN Configuration", err.Error())
return
}

var plan model
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)

if resp.Diagnostics.HasError() {
return
}

plan.ID = types.StringValue(strconv.FormatInt(time.Now().UTC().UnixMilli(), 10))
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}

func (r *Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
if err := r.client.ApplyConfig(ctx); err != nil {
resp.Diagnostics.AddError("Unable to Re-Apply SDN Configuration", err.Error())
return
}
}
Loading