Skip to content

Commit

Permalink
initial work converting primitives from set to map
Browse files Browse the repository at this point in the history
TODO:
- tests
- ensure primitive ID survives
  • Loading branch information
chrismarget-j committed Dec 17, 2024
1 parent 4513764 commit e3010f8
Show file tree
Hide file tree
Showing 22 changed files with 320 additions and 390 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/Juniper/apstra-go-sdk/apstra"
"github.com/Juniper/terraform-provider-apstra/apstra/blueprint/connectivity_templates/primitives"
"github.com/Juniper/terraform-provider-apstra/apstra/utils"
"github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/diag"
Expand All @@ -22,10 +23,10 @@ type ConnectivityTemplateInterface struct {
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Tags types.Set `tfsdk:"tags"`
IpLinks types.Set `tfsdk:"ip_links"`
RoutingZoneConstraints types.Set `tfsdk:"routing_zone_constraints"`
VirtualNetworkMultiples types.Set `tfsdk:"virtual_network_multiples"`
VirtualNetworkSingles types.Set `tfsdk:"virtual_network_singles"`
IpLinks types.Map `tfsdk:"ip_links"`
RoutingZoneConstraints types.Map `tfsdk:"routing_zone_constraints"`
VirtualNetworkMultiples types.Map `tfsdk:"virtual_network_multiples"`
VirtualNetworkSingles types.Map `tfsdk:"virtual_network_singles"`
}

func (o ConnectivityTemplateInterface) ResourceAttributes() map[string]resourceSchema.Attribute {
Expand Down Expand Up @@ -60,37 +61,37 @@ func (o ConnectivityTemplateInterface) ResourceAttributes() map[string]resourceS
setvalidator.ValueStringsAre(stringvalidator.LengthAtLeast(1)),
},
},
"ip_links": resourceSchema.SetNestedAttribute{
MarkdownDescription: "Set of *IP Link* Primitives in this Connectivity Template",
"ip_links": resourceSchema.MapNestedAttribute{
MarkdownDescription: "Map of *IP Link* Primitives in this Connectivity Template",
NestedObject: resourceSchema.NestedAttributeObject{
Attributes: primitives.IpLink{}.ResourceAttributes(),
},
Optional: true,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
Validators: []validator.Map{mapvalidator.SizeAtLeast(1)},
},
"routing_zone_constraints": resourceSchema.SetNestedAttribute{
MarkdownDescription: "Set of *Routing Zone Constraint* Primitives in this Connectivity Template",
"routing_zone_constraints": resourceSchema.MapNestedAttribute{
MarkdownDescription: "Map of *Routing Zone Constraint* Primitives in this Connectivity Template",
NestedObject: resourceSchema.NestedAttributeObject{
Attributes: primitives.RoutingZoneConstraint{}.ResourceAttributes(),
},
Optional: true,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
Validators: []validator.Map{mapvalidator.SizeAtLeast(1)},
},
"virtual_network_multiples": resourceSchema.SetNestedAttribute{
MarkdownDescription: "Set of *Virtual Network (Multiple)* Primitives in this Connectivity Template",
"virtual_network_multiples": resourceSchema.MapNestedAttribute{
MarkdownDescription: "Map of *Virtual Network (Multiple)* Primitives in this Connectivity Template",
NestedObject: resourceSchema.NestedAttributeObject{
Attributes: primitives.VirtualNetworkMultiple{}.ResourceAttributes(),
},
Optional: true,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
Validators: []validator.Map{mapvalidator.SizeAtLeast(1)},
},
"virtual_network_singles": resourceSchema.SetNestedAttribute{
MarkdownDescription: "Set of *Virtual Network (Single)* Primitives in this Connectivity Template",
"virtual_network_singles": resourceSchema.MapNestedAttribute{
MarkdownDescription: "Map of *Virtual Network (Single)* Primitives in this Connectivity Template",
NestedObject: resourceSchema.NestedAttributeObject{
Attributes: primitives.VirtualNetworkSingle{}.ResourceAttributes(),
},
Optional: true,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
Validators: []validator.Map{mapvalidator.SizeAtLeast(1)},
},
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/Juniper/apstra-go-sdk/apstra"
"github.com/Juniper/terraform-provider-apstra/apstra/blueprint/connectivity_templates/primitives"
"github.com/Juniper/terraform-provider-apstra/apstra/utils"
"github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/diag"
Expand All @@ -22,7 +23,7 @@ type ConnectivityTemplateLoopback struct {
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Tags types.Set `tfsdk:"tags"`
BgpPeeringIpEndpoints types.Set `tfsdk:"bgp_peering_ip_endpoints"`
BgpPeeringIpEndpoints types.Map `tfsdk:"bgp_peering_ip_endpoints"`
}

func (o ConnectivityTemplateLoopback) ResourceAttributes() map[string]resourceSchema.Attribute {
Expand Down Expand Up @@ -57,13 +58,13 @@ func (o ConnectivityTemplateLoopback) ResourceAttributes() map[string]resourceSc
setvalidator.ValueStringsAre(stringvalidator.LengthAtLeast(1)),
},
},
"bgp_peering_ip_endpoints": resourceSchema.SetNestedAttribute{
"bgp_peering_ip_endpoints": resourceSchema.MapNestedAttribute{
MarkdownDescription: "Set of *BGP Peering (IP Endpoint)* Primitives in this Connectivity Template",
NestedObject: resourceSchema.NestedAttributeObject{
Attributes: primitives.BgpPeeringIpEndpoint{}.ResourceAttributes(),
},
Optional: true,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
Validators: []validator.Map{mapvalidator.SizeAtLeast(1)},
},
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/Juniper/apstra-go-sdk/apstra"
"github.com/Juniper/terraform-provider-apstra/apstra/blueprint/connectivity_templates/primitives"
"github.com/Juniper/terraform-provider-apstra/apstra/utils"
"github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/diag"
Expand All @@ -22,8 +23,8 @@ type ConnectivityTemplateSvi struct {
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Tags types.Set `tfsdk:"tags"`
BgpPeeringIpEndpoints types.Set `tfsdk:"bgp_peering_ip_endpoints"`
DynamicBgpPeerings types.Set `tfsdk:"dynamic_bgp_peerings"`
BgpPeeringIpEndpoints types.Map `tfsdk:"bgp_peering_ip_endpoints"`
DynamicBgpPeerings types.Map `tfsdk:"dynamic_bgp_peerings"`
}

func (o ConnectivityTemplateSvi) ResourceAttributes() map[string]resourceSchema.Attribute {
Expand Down Expand Up @@ -58,17 +59,17 @@ func (o ConnectivityTemplateSvi) ResourceAttributes() map[string]resourceSchema.
setvalidator.ValueStringsAre(stringvalidator.LengthAtLeast(1)),
},
},
"bgp_peering_ip_endpoints": resourceSchema.SetNestedAttribute{
MarkdownDescription: "Set of *BGP Peering (IP Endpoint)* Primitives in this Connectivity Template",
"bgp_peering_ip_endpoints": resourceSchema.MapNestedAttribute{
MarkdownDescription: "Map of *BGP Peering (IP Endpoint)* Primitives in this Connectivity Template",
NestedObject: resourceSchema.NestedAttributeObject{Attributes: primitives.BgpPeeringIpEndpoint{}.ResourceAttributes()},
Optional: true,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
Validators: []validator.Map{mapvalidator.SizeAtLeast(1)},
},
"dynamic_bgp_peerings": resourceSchema.SetNestedAttribute{
MarkdownDescription: "Set of *Dynamic BGP Peering* Primitives in this Connectivity Template",
"dynamic_bgp_peerings": resourceSchema.MapNestedAttribute{
MarkdownDescription: "Map of *Dynamic BGP Peering* Primitives in this Connectivity Template",
NestedObject: resourceSchema.NestedAttributeObject{Attributes: primitives.DynamicBgpPeering{}.ResourceAttributes()},
Optional: true,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
Validators: []validator.Map{mapvalidator.SizeAtLeast(1)},
},
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/Juniper/apstra-go-sdk/apstra"
"github.com/Juniper/terraform-provider-apstra/apstra/blueprint/connectivity_templates/primitives"
"github.com/Juniper/terraform-provider-apstra/apstra/utils"
"github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/diag"
Expand All @@ -23,7 +24,7 @@ type ConnectivityTemplateSystem struct {
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Tags types.Set `tfsdk:"tags"`
CustomStaticRoutes types.Set `tfsdk:"custom_static_routes"`
CustomStaticRoutes types.Map `tfsdk:"custom_static_routes"`
}

func (o ConnectivityTemplateSystem) ResourceAttributes() map[string]resourceSchema.Attribute {
Expand Down Expand Up @@ -58,13 +59,13 @@ func (o ConnectivityTemplateSystem) ResourceAttributes() map[string]resourceSche
setvalidator.ValueStringsAre(stringvalidator.LengthAtLeast(1)),
},
},
"custom_static_routes": resourceSchema.SetNestedAttribute{
MarkdownDescription: "Set of *Custom Static Route* Primitives in this Connectivity Template.",
"custom_static_routes": resourceSchema.MapNestedAttribute{
MarkdownDescription: "Map of *Custom Static Route* Primitives in this Connectivity Template.",
NestedObject: resourceSchema.NestedAttributeObject{
Attributes: primitives.CustomStaticRoute{}.ResourceAttributes(),
},
Optional: true,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
Validators: []validator.Map{mapvalidator.SizeAtLeast(1)},
},
}
}
Expand All @@ -74,18 +75,19 @@ func (o *ConnectivityTemplateSystem) ValidateConfig(ctx context.Context, diags *
return
}

var customStaticRoutes []primitives.CustomStaticRoute
customStaticRoutes := make(map[string]primitives.CustomStaticRoute)
diags.Append(o.CustomStaticRoutes.ElementsAs(ctx, &customStaticRoutes, false)...)
if diags.HasError() {
return
}

for i, attrVal := range o.CustomStaticRoutes.Elements() {
if attrVal.IsUnknown() {
for k, v := range o.CustomStaticRoutes.Elements() {
if v.IsUnknown() {
continue
}

customStaticRoutes[i].ValidateConfig(ctx, path.Root("custom_static_routes").AtSetValue(attrVal), diags)
customStaticRoute := customStaticRoutes[k]
customStaticRoute.ValidateConfig(ctx, path.Root("custom_static_routes").AtMapKey(k), diags)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/Juniper/terraform-provider-apstra/apstra/utils"
apstravalidator "github.com/Juniper/terraform-provider-apstra/apstra/validator"
"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/attr"
dataSourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
Expand All @@ -25,7 +25,6 @@ import (
)

type BgpPeeringGenericSystem struct {
Name types.String `tfsdk:"name"`
Ttl types.Int64 `tfsdk:"ttl"`
BfdEnabled types.Bool `tfsdk:"bfd_enabled"`
Password types.String `tfsdk:"password"`
Expand All @@ -37,12 +36,11 @@ type BgpPeeringGenericSystem struct {
NeighborAsnDynamic types.Bool `tfsdk:"neighbor_asn_dynamic"`
PeerFromLoopback types.Bool `tfsdk:"peer_from_loopback"`
PeerTo types.String `tfsdk:"peer_to"`
RoutingPolicies types.Set `tfsdk:"routing_policies"`
RoutingPolicies types.Map `tfsdk:"routing_policies"`
}

func (o BgpPeeringGenericSystem) AttrTypes() map[string]attr.Type {
return map[string]attr.Type{
"name": types.StringType,
"ttl": types.Int64Type,
"bfd_enabled": types.BoolType,
"password": types.StringType,
Expand All @@ -54,17 +52,12 @@ func (o BgpPeeringGenericSystem) AttrTypes() map[string]attr.Type {
"neighbor_asn_dynamic": types.BoolType,
"peer_from_loopback": types.BoolType,
"peer_to": types.StringType,
"routing_policies": types.SetType{ElemType: types.ObjectType{AttrTypes: RoutingPolicy{}.AttrTypes()}},
"routing_policies": types.MapType{ElemType: types.ObjectType{AttrTypes: RoutingPolicy{}.AttrTypes()}},
}
}

func (o BgpPeeringGenericSystem) ResourceAttributes() map[string]resourceSchema.Attribute {
return map[string]resourceSchema.Attribute{
"name": resourceSchema.StringAttribute{
MarkdownDescription: "Label used by the web UI on the Primitive \"block\" in the Connectivity Template.",
Required: true,
Validators: []validator.String{stringvalidator.LengthAtLeast(1)},
},
"ttl": resourceSchema.Int64Attribute{
MarkdownDescription: "BGP Time To Live. Omit to use device defaults.",
Optional: true,
Expand Down Expand Up @@ -141,13 +134,13 @@ func (o BgpPeeringGenericSystem) ResourceAttributes() map[string]resourceSchema.
Required: true,
Validators: []validator.String{stringvalidator.OneOf(utils.PeerToTypes()...)},
},
"routing_policies": resourceSchema.SetNestedAttribute{
MarkdownDescription: "Set of Routing Policy Primitives to be used with this *Protocol Endpoint*.",
"routing_policies": resourceSchema.MapNestedAttribute{
MarkdownDescription: "Map of Routing Policy Primitives to be used with this *Protocol Endpoint*.",
NestedObject: resourceSchema.NestedAttributeObject{
Attributes: RoutingPolicy{}.ResourceAttributes(),
},
Optional: true,
Validators: []validator.Set{setvalidator.SizeAtLeast(1)},
Validators: []validator.Map{mapvalidator.SizeAtLeast(1)},
},
}
}
Expand Down Expand Up @@ -192,7 +185,6 @@ func (o BgpPeeringGenericSystem) attributes(_ context.Context, diags *diag.Diagn
}

return &apstra.ConnectivityTemplatePrimitiveAttributesAttachBgpOverSubinterfacesOrSvi{
// Label: o.Name.ValueString(), // todo is this necessary?
Bfd: o.BfdEnabled.ValueBool(),
Holdtime: holdTime,
Ipv4Safi: o.Ipv4AddressingType.ValueString() != utils.StringersToFriendlyString(enum.InterfaceNumberingIpv4TypeNone),
Expand All @@ -211,7 +203,7 @@ func (o BgpPeeringGenericSystem) attributes(_ context.Context, diags *diag.Diagn

func (o BgpPeeringGenericSystem) primitive(ctx context.Context, diags *diag.Diagnostics) *apstra.ConnectivityTemplatePrimitive {
result := apstra.ConnectivityTemplatePrimitive{
Label: o.Name.ValueString(),
// Label: // set by caller
Attributes: o.attributes(ctx, diags),
// Subpolicies: // set below
}
Expand All @@ -221,16 +213,19 @@ func (o BgpPeeringGenericSystem) primitive(ctx context.Context, diags *diag.Diag
return &result
}

func BgpPeeringGenericSystemSubpolicies(ctx context.Context, bgpPeeringGenericSystemSet types.Set, diags *diag.Diagnostics) []*apstra.ConnectivityTemplatePrimitive {
var bgpPeeringGenericSystems []BgpPeeringGenericSystem
diags.Append(bgpPeeringGenericSystemSet.ElementsAs(ctx, &bgpPeeringGenericSystems, false)...)
func BgpPeeringGenericSystemSubpolicies(ctx context.Context, bgpPeeringGenericSystemMap types.Map, diags *diag.Diagnostics) []*apstra.ConnectivityTemplatePrimitive {
var bgpPeeringGenericSystems map[string]BgpPeeringGenericSystem
diags.Append(bgpPeeringGenericSystemMap.ElementsAs(ctx, &bgpPeeringGenericSystems, false)...)
if diags.HasError() {
return nil
}

subpolicies := make([]*apstra.ConnectivityTemplatePrimitive, len(bgpPeeringGenericSystems))
for i, bgpPeeringGenericSystem := range bgpPeeringGenericSystems {
subpolicies[i] = bgpPeeringGenericSystem.primitive(ctx, diags)
i := 0
for k, v := range bgpPeeringGenericSystems {
subpolicies[i] = v.primitive(ctx, diags)
subpolicies[i].Label = k
i++
}

return subpolicies
Expand Down Expand Up @@ -264,8 +259,8 @@ func newBgpPeeringGenericSystem(_ context.Context, in *apstra.ConnectivityTempla
return result
}

func BgpPeeringGenericSystemPrimitivesFromSubpolicies(ctx context.Context, subpolicies []*apstra.ConnectivityTemplatePrimitive, diags *diag.Diagnostics) types.Set {
var result []BgpPeeringGenericSystem
func BgpPeeringGenericSystemPrimitivesFromSubpolicies(ctx context.Context, subpolicies []*apstra.ConnectivityTemplatePrimitive, diags *diag.Diagnostics) types.Map {
result := make(map[string]BgpPeeringGenericSystem, len(subpolicies))

for i, subpolicy := range subpolicies {
if subpolicy == nil {
Expand All @@ -283,14 +278,13 @@ func BgpPeeringGenericSystemPrimitivesFromSubpolicies(ctx context.Context, subpo
}

newPrimitive := newBgpPeeringGenericSystem(ctx, p, diags)
newPrimitive.Name = utils.StringValueOrNull(ctx, subpolicy.Label, diags)
newPrimitive.RoutingPolicies = RoutingPolicyPrimitivesFromSubpolicies(ctx, subpolicy.Subpolicies, diags)
result = append(result, newPrimitive)
result[subpolicy.Label] = newPrimitive
}
}
if diags.HasError() {
return types.SetNull(types.ObjectType{AttrTypes: BgpPeeringGenericSystem{}.AttrTypes()})
return types.MapNull(types.ObjectType{AttrTypes: BgpPeeringGenericSystem{}.AttrTypes()})
}

return utils.SetValueOrNull(ctx, types.ObjectType{AttrTypes: BgpPeeringGenericSystem{}.AttrTypes()}, result, diags)
return utils.MapValueOrNull(ctx, types.ObjectType{AttrTypes: BgpPeeringGenericSystem{}.AttrTypes()}, result, diags)
}
Loading

0 comments on commit e3010f8

Please sign in to comment.