Files
terraform-provider-unifi/internal/provider/firewall/resource_firewall_zone.go
Mateusz Filipowicz b9284f7758 docs: improve documentation for 1.0.0 release (#75)
* docs: add examples and recreate TF documentation

* update readme

* add information about experimental support of firewall zones
2025-03-22 19:13:16 +01:00

132 lines
4.8 KiB
Go

package firewall
import (
"context"
"github.com/filipowm/go-unifi/unifi/features"
ut "github.com/filipowm/terraform-provider-unifi/internal/provider/types"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/filipowm/go-unifi/unifi"
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
"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 = &firewallZoneResource{}
_ resource.ResourceWithConfigure = &firewallZoneResource{}
_ resource.ResourceWithImportState = &firewallZoneResource{}
_ resource.ResourceWithModifyPlan = &firewallZoneResource{}
_ base.Resource = &firewallZoneResource{}
)
// firewallZoneModel represents the data model for a UniFi Firewall Zone
type firewallZoneModel struct {
base.Model
Name types.String `tfsdk:"name"`
Networks types.List `tfsdk:"networks"`
}
// AsUnifiModel converts the Terraform model to the UniFi API model
func (m *firewallZoneModel) AsUnifiModel(_ context.Context) (interface{}, diag.Diagnostics) {
diags := diag.Diagnostics{}
var networkIDs []string
diags.Append(ut.ListElementsAs(m.Networks, &networkIDs)...)
if diags.HasError() {
return nil, diags
}
return &unifi.FirewallZone{
ID: m.ID.ValueString(),
Name: m.Name.ValueString(),
NetworkIDs: networkIDs,
}, diags
}
// Merge updates the Terraform model with values from the UniFi API model
func (m *firewallZoneModel) Merge(ctx context.Context, other interface{}) diag.Diagnostics {
var diags diag.Diagnostics
model, ok := other.(*unifi.FirewallZone)
if !ok {
diags.AddError("Invalid model type", "Expected *unifi.FirewallZone")
return diags
}
m.ID = types.StringValue(model.ID)
m.Name = types.StringValue(model.Name)
networkIDs, d := types.ListValueFrom(ctx, types.StringType, model.NetworkIDs)
diags = append(diags, d...)
m.Networks = networkIDs
return diags
}
type firewallZoneResource struct {
*base.GenericResource[*firewallZoneModel]
}
func (r *firewallZoneResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
resp.Diagnostics.Append(r.RequireMinVersion("9.0.0")...)
site, diags := r.GetClient().ResolveSiteFromConfig(ctx, req.Config)
if diags.HasError() {
resp.Diagnostics.Append(diags...)
return
}
resp.Diagnostics.Append(r.RequireFeaturesEnabled(ctx, site, features.ZoneBasedFirewall, features.ZoneBasedFirewallMigration)...)
}
// NewFirewallZoneResource creates a new instance of the firewall zone resource
func NewFirewallZoneResource() resource.Resource {
return &firewallZoneResource{
GenericResource: base.NewGenericResource(
"unifi_firewall_zone",
func() *firewallZoneModel { return &firewallZoneModel{} },
base.ResourceFunctions{
Read: func(ctx context.Context, client *base.Client, site, id string) (interface{}, error) {
return client.GetFirewallZone(ctx, site, id)
},
Create: func(ctx context.Context, client *base.Client, site string, model interface{}) (interface{}, error) {
return client.CreateFirewallZone(ctx, site, model.(*unifi.FirewallZone))
},
Update: func(ctx context.Context, client *base.Client, site string, model interface{}) (interface{}, error) {
return client.UpdateFirewallZone(ctx, site, model.(*unifi.FirewallZone))
},
Delete: func(ctx context.Context, client *base.Client, site, id string) error {
return client.DeleteFirewallZone(ctx, site, id)
},
},
),
}
}
// Schema defines the schema for the resource
func (r *firewallZoneResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "The `unifi_firewall_zone` resource manages firewall zones in the UniFi controller.\n\n" +
"Firewall zones allow you to group networks together for firewall rule application. " +
"This resource allows you to create, update, and delete firewall zones.\n\n" +
"!> This is experimental feature, that requires UniFi OS 9.0.0 or later and Zone Based Firewall feature enabled. " +
"Check [official documentation](https://help.ui.com/hc/en-us/articles/28223082254743-Migrating-to-Zone-Based-Firewalls-in-UniFi) how to migate to Zone-Based firewalls.",
Attributes: map[string]schema.Attribute{
"id": ut.ID(),
"site": ut.SiteAttribute(),
"name": schema.StringAttribute{
MarkdownDescription: "The name of the firewall zone.",
Required: true,
},
"networks": schema.ListAttribute{
MarkdownDescription: "List of network IDs to include in this firewall zone.",
Optional: true,
Computed: true,
ElementType: types.StringType,
Default: ut.DefaultEmptyList(types.StringType),
},
},
}
}