Skip to content

Commit

Permalink
add support for junos_evpn_irb_mode
Browse files Browse the repository at this point in the history
  • Loading branch information
chrismarget-j committed Nov 1, 2023
1 parent a78a705 commit 568ea87
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 16 deletions.
2 changes: 2 additions & 0 deletions apstra/blueprint/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const (
errApiGetWithTypeAndId = "API error getting %s %q"
errApiPatchWithTypeAndId = "API error patching %s %q"
errProviderBug = "Provider Bug. Please report this issue to the provider maintainers."
errApiCompatibility = "Apstra API version incompatibility"
errInvalidConfig = "invalid configuration"

ErrDCBlueprintCreate = "Failed to create client for Datacenter Blueprint %s"
)
96 changes: 83 additions & 13 deletions apstra/blueprint/datacenter_routing_zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/Juniper/terraform-provider-apstra/apstra/design"
"github.com/Juniper/terraform-provider-apstra/apstra/resources"
"github.com/Juniper/terraform-provider-apstra/apstra/utils"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
Expand All @@ -23,9 +25,7 @@ import (
"regexp"
)

const (
errInvalidConfig = "invalid configuration"
)
var junosIrbModeDefault = apstra.JunosEvpnIrbModeAsymmetric.Value

type DatacenterRoutingZone struct {
Id types.String `tfsdk:"id"`
Expand All @@ -39,6 +39,7 @@ type DatacenterRoutingZone struct {
RoutingPolicyId types.String `tfsdk:"routing_policy_id"`
ImportRouteTargets types.Set `tfsdk:"import_route_targets"`
ExportRouteTargets types.Set `tfsdk:"export_route_targets"`
JunosIrbMode types.String `tfsdk:"junos_irb_mode"`
}

func (o DatacenterRoutingZone) DataSourceAttributes() map[string]dataSourceSchema.Attribute {
Expand Down Expand Up @@ -113,6 +114,12 @@ func (o DatacenterRoutingZone) DataSourceAttributes() map[string]dataSourceSchem
Computed: true,
ElementType: types.StringType,
},
"junos_irb_mode": dataSourceSchema.StringAttribute{
MarkdownDescription: "Symmetric IRB Routing for EVPN on Junos devices makes use of an L3 VNI for " +
"inter-subnet routing which is embedded into EVPN Type2-routes to support better scaling for " +
"networks with large amounts of VLANs.",
Computed: true,
},
}
}

Expand Down Expand Up @@ -157,17 +164,21 @@ func (o DatacenterRoutingZone) DataSourceFilterAttributes() map[string]dataSourc
"Set this attribute in an EVPN blueprint to use a non-default policy.",
Optional: true,
},
"import_route_targets": resourceSchema.SetAttribute{
"import_route_targets": dataSourceSchema.SetAttribute{
MarkdownDescription: "This is a set of *required* RTs, not an exact-match list.",
Optional: true,
ElementType: types.StringType,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
},
"export_route_targets": resourceSchema.SetAttribute{
"export_route_targets": dataSourceSchema.SetAttribute{
MarkdownDescription: "This is a set of *required* RTs, not an exact-match list.",
Optional: true,
ElementType: types.StringType,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
},
"junos_irb_mode": dataSourceSchema.StringAttribute{
MarkdownDescription: "Symmetric IRB Routing for EVPN on Junos devices makes use of an L3 VNI for " +
"inter-subnet routing which is embedded into EVPN Type2-routes to support better scaling for " +
"networks with large amounts of VLANs.",
Optional: true,
},
}
}
Expand Down Expand Up @@ -253,10 +264,30 @@ func (o DatacenterRoutingZone) ResourceAttributes() map[string]resourceSchema.At
setvalidator.ValueStringsAre(apstravalidator.ParseRT()),
},
},
"junos_irb_mode": resourceSchema.StringAttribute{
MarkdownDescription: fmt.Sprintf("Symmetric IRB Routing for EVPN on Junos devices makes use of "+
"an L3 VNI for inter-subnet routing which is embedded into EVPN Type2-routes to support better "+
"scaling for networks with large amounts of VLANs. Applicable only to Apstra 4.2.0+. When omitted, "+
"Routing Zones in Apstra 4.2.0 and later will be configured with mode `%s`.", junosIrbModeDefault),
Optional: true,
Computed: true,
Validators: []validator.String{stringvalidator.OneOf(
apstra.JunosEvpnIrbModeSymmetric.Value,
apstra.JunosEvpnIrbModeAsymmetric.Value,
)},
// Default: DO NOT USE stringdefault.StaticString(apstra.JunosEvpnIrbModeAsymmetric.Value) here
// because that will set the attribute for Apstra < 4.2.0 (which do not support it) leading to
// confusion.
},
}
}

func (o *DatacenterRoutingZone) Request(ctx context.Context, client *apstra.Client, diags *diag.Diagnostics) *apstra.SecurityZoneData {
o.setDefaults(ctx, client, diags)
if diags.HasError() {
return nil
}

var vlan *apstra.Vlan
if !o.VlanId.IsNull() && !o.VlanId.IsUnknown() {
v := apstra.Vlan(o.VlanId.ValueInt64())
Expand Down Expand Up @@ -290,13 +321,19 @@ func (o *DatacenterRoutingZone) Request(ctx context.Context, client *apstra.Clie
return nil
}

var junosEvpnIrbMode *apstra.JunosEvpnIrbMode
if !o.JunosIrbMode.IsNull() {
junosEvpnIrbMode = &apstra.JunosEvpnIrbModeAsymmetric
}

return &apstra.SecurityZoneData{
SzType: apstra.SecurityZoneTypeEVPN,
VrfName: o.Name.ValueString(),
Label: o.Name.ValueString(),
RoutingPolicyId: apstra.ObjectId(o.RoutingPolicyId.ValueString()),
VlanId: vlan,
VniId: vni,
SzType: apstra.SecurityZoneTypeEVPN,
VrfName: o.Name.ValueString(),
Label: o.Name.ValueString(),
RoutingPolicyId: apstra.ObjectId(o.RoutingPolicyId.ValueString()),
VlanId: vlan,
VniId: vni,
JunosEvpnIrbMode: junosEvpnIrbMode,
RtPolicy: &apstra.RtPolicy{
ImportRTs: importRTs,
ExportRTs: exportRTs,
Expand Down Expand Up @@ -341,6 +378,11 @@ func (o *DatacenterRoutingZone) LoadApiData(ctx context.Context, sz *apstra.Secu
if sz.RtPolicy != nil && sz.RtPolicy.ExportRTs != nil {
o.ExportRouteTargets = utils.SetValueOrNull(ctx, types.StringType, sz.RtPolicy.ExportRTs, diags)
}

o.JunosIrbMode = types.StringNull()
if sz.JunosEvpnIrbMode != nil {
o.JunosIrbMode = types.StringValue(sz.JunosEvpnIrbMode.Value)
}
}

func (o *DatacenterRoutingZone) LoadApiDhcpServers(ctx context.Context, IPs []net.IP, diags *diag.Diagnostics) {
Expand Down Expand Up @@ -472,5 +514,33 @@ func (o *DatacenterRoutingZone) szNodeQueryAttributes(name string) []apstra.QEEA
result = append(result, apstra.QEEAttribute{Key: "vlan_id", Value: apstra.QEIntVal(int(o.VlanId.ValueInt64()))})
}

if utils.Known(o.JunosIrbMode) {
result = append(result, apstra.QEEAttribute{Key: "junos_evpn_irb_mode", Value: apstra.QEStringVal(o.JunosIrbMode.ValueString())})
}

return result
}

func (o *DatacenterRoutingZone) setDefaults(_ context.Context, client *apstra.Client, diags *diag.Diagnostics) {
apiVersion, err := version.NewVersion(client.ApiVersion())
if err != nil {
diags.AddError("failed parsing API version", err.Error())
return
}
junosIrbModeMinVersion, _ := version.NewVersion("4.2.0")

if utils.Known(o.JunosIrbMode) && apiVersion.LessThan(junosIrbModeMinVersion) {
// junos_irb_mode is set, but Apstra version < 4.2.0
diags.Append(validatordiag.InvalidAttributeValueDiagnostic(
path.Root("junos_irb_mode"),
errApiCompatibility,
fmt.Sprintf("junos_irb_mode must be set with Apstra API version %s", apiVersion),
))
}

if !utils.Known(o.JunosIrbMode) && apiVersion.GreaterThanOrEqual(junosIrbModeMinVersion) {
// junos_irb_mode not set, Apstra version >= 4.2.0, so set the default value
o.JunosIrbMode = types.StringValue(junosIrbModeDefault)
}

}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.20

require (
github.com/IBM/netaddr v1.5.0
github.com/Juniper/apstra-go-sdk v0.0.0-20231024231608-5d733c01a440
github.com/Juniper/apstra-go-sdk v0.0.0-20231031171315-81c759655138
github.com/chrismarget-j/go-licenses v0.0.0-20230424163011-d60082a506e0
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/terraform-plugin-docs v0.13.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/IBM/netaddr v1.5.0 h1:IJlFZe1+nFs09TeMB/HOP4+xBnX2iM/xgiDOgZgTJq0=
github.com/IBM/netaddr v1.5.0/go.mod h1:DDBPeYgbFzoXHjSz9Jwk7K8wmWV4+a/Kv0LqRnb8we4=
github.com/Juniper/apstra-go-sdk v0.0.0-20231024231608-5d733c01a440 h1:zAE3k3T4EhBCJpoNrCWbv3Sow92+11O1vAhF1R/wsD0=
github.com/Juniper/apstra-go-sdk v0.0.0-20231024231608-5d733c01a440/go.mod h1:It+5cLgOj77K+s+7m5Nsnbms3Tu/4ObqDuBjsTR2Oh0=
github.com/Juniper/apstra-go-sdk v0.0.0-20231031171315-81c759655138 h1:0qpDpmea2PPaRoYZkpl79fBqXCCNcdTaryE/BMcKmsQ=
github.com/Juniper/apstra-go-sdk v0.0.0-20231031171315-81c759655138/go.mod h1:It+5cLgOj77K+s+7m5Nsnbms3Tu/4ObqDuBjsTR2Oh0=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
Expand Down

0 comments on commit 568ea87

Please sign in to comment.