Skip to content

Commit

Permalink
Merge pull request #463 from Juniper/feat/456-generic-system-deploy-mode
Browse files Browse the repository at this point in the history
Add `deploy_mode` attribute to `apstra_datacenter_generic_system` resource
  • Loading branch information
chrismarget-j authored Nov 21, 2023
2 parents 038474c + 31e1177 commit 2a29dab
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 10 deletions.
35 changes: 35 additions & 0 deletions apstra/blueprint/datacenter_generic_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand All @@ -36,6 +37,7 @@ type DatacenterGenericSystem struct {
LoopbackIpv4 cidrtypes.IPv4Prefix `tfsdk:"loopback_ipv4"`
LoopbackIpv6 cidrtypes.IPv6Prefix `tfsdk:"loopback_ipv6"`
External types.Bool `tfsdk:"external"`
DeployMode types.String `tfsdk:"deploy_mode"`
}

func (o DatacenterGenericSystem) ResourceAttributes() map[string]resourceSchema.Attribute {
Expand Down Expand Up @@ -109,6 +111,14 @@ func (o DatacenterGenericSystem) ResourceAttributes() map[string]resourceSchema.
Default: booldefault.StaticBool(false),
PlanModifiers: []planmodifier.Bool{boolplanmodifier.RequiresReplace()},
},
"deploy_mode": resourceSchema.StringAttribute{
MarkdownDescription: fmt.Sprintf("Set the Apstra Deploy Mode for this Generic System. Default: `%s`",
apstra.NodeDeployModeDeploy),
Optional: true,
Computed: true,
Default: stringdefault.StaticString(apstra.NodeDeployModeDeploy.String()),
Validators: []validator.String{stringvalidator.OneOf(utils.AllNodeDeployModes()...)},
},
}
}

Expand Down Expand Up @@ -268,6 +278,14 @@ func (o *DatacenterGenericSystem) ReadSystemProperties(ctx context.Context, bp *
o.External = types.BoolValue(nodeInfo.External)
}

if overwriteKnownValues || o.DeployMode.IsUnknown() {
deployMode, err := utils.GetNodeDeployMode(ctx, bp, o.Id.ValueString())
if err != nil {
return err
}
o.DeployMode = types.StringValue(deployMode)
}

// asn isn't computed, so will never be unknown
if overwriteKnownValues && nodeInfo.Asn != nil {
o.Asn = types.Int64Value(int64(*nodeInfo.Asn))
Expand Down Expand Up @@ -643,16 +661,33 @@ func (o *DatacenterGenericSystem) SetProperties(ctx context.Context, bp *apstra.
// set ASN if we don't have prior state or the ASN needs to be updated
if state == nil || !o.Asn.Equal(state.Asn) {
o.setAsn(ctx, bp, diags)
if diags.HasError() {
return
}
}

// set loopback v4 if we don't have prior state or the v4 address needs to be updated
if state == nil || !o.LoopbackIpv4.Equal(state.LoopbackIpv4) {
o.setLoopbackIPv4(ctx, bp, diags)
if diags.HasError() {
return
}
}

// set loopback v6 if we don't have prior state or the v6 address needs to be updated
if state == nil || !o.LoopbackIpv6.Equal(state.LoopbackIpv6) {
o.setLoopbackIPv6(ctx, bp, diags)
if diags.HasError() {
return
}
}

// set deploy mode if we don't have prior state or the deploy mode needs to be updated
if state == nil || !o.DeployMode.Equal(state.DeployMode) {
err := utils.SetNodeDeployMode(ctx, bp, o.Id.ValueString(), o.DeployMode.ValueString())
if err != nil {
diags.AddError("failed to set node deploy mode", err.Error())
}
}
}

Expand Down
113 changes: 103 additions & 10 deletions apstra/resource_datacenter_generic_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ resource "apstra_datacenter_generic_system" "test" {
asn = %s
loopback_ipv4 = %s
loopback_ipv6 = %s
tags = %s
links = [
tags = %s
deploy_mode = %s
links = [
%s ]
}
`
Expand Down Expand Up @@ -115,14 +116,15 @@ func TestResourceDatacenterGenericSystem_A(t *testing.T) {
}

type genericSystem struct {
bpId string
name string
hostname string
asn *int
loopback4 *net.IPNet
loopback6 *net.IPNet
tags tagSlice
links []link
bpId string
name string
hostname string
asn *int
loopback4 *net.IPNet
loopback6 *net.IPNet
tags tagSlice
deployMode string
links []link
}
renderGenericSystem := func(in genericSystem) string {
return fmt.Sprintf(resourceDataCenterGenericSystemHCL,
Expand All @@ -133,6 +135,7 @@ func TestResourceDatacenterGenericSystem_A(t *testing.T) {
ipOrNull(in.loopback4),
ipOrNull(in.loopback6),
renderTags(in.tags),
stringOrNull(in.deployMode),
renderLinks(in.links),
)
}
Expand Down Expand Up @@ -346,6 +349,96 @@ func TestResourceDatacenterGenericSystem_A(t *testing.T) {
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.tags.0", "c"),
}...),
},
{
genericSystem: genericSystem{
//name: "foo",
//hostname: "foo.com",
//tags: []string{"a"},
deployMode: apstra.NodeDeployModeReady.String(),
links: []link{
{
lagMode: apstra.RackLinkLagModePassive,
groupLabel: "bar",
targetSwitchId: leafIds[0],
targetSwitchIf: "xe-0/0/6",
targetSwitchTf: 1,
tags: []string{"c"},
},
{
lagMode: apstra.RackLinkLagModePassive,
groupLabel: "bar",
targetSwitchId: leafIds[0],
targetSwitchIf: "xe-0/0/7",
targetSwitchTf: 1,
tags: []string{"c"},
},
},
},
testCheckFunc: resource.ComposeAggregateTestCheckFunc([]resource.TestCheckFunc{
resource.TestCheckNoResourceAttr("apstra_datacenter_generic_system.test", "asn"),
resource.TestCheckNoResourceAttr("apstra_datacenter_generic_system.test", "loopback_ipv4"),
resource.TestCheckNoResourceAttr("apstra_datacenter_generic_system.test", "loopback_ipv6"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "deploy_mode", apstra.NodeDeployModeReady.String()),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.#", "2"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.group_label", "bar"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.lag_mode", apstra.RackLinkLagModePassive.String()),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.target_switch_if_name", "xe-0/0/6"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.target_switch_if_transform_id", "1"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.tags.#", "1"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.tags.0", "c"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.group_label", "bar"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.lag_mode", apstra.RackLinkLagModePassive.String()),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.target_switch_if_name", "xe-0/0/7"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.target_switch_if_transform_id", "1"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.tags.#", "1"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.tags.0", "c"),
}...),
},
{
genericSystem: genericSystem{
//name: "foo",
//hostname: "foo.com",
//tags: []string{"a"},
deployMode: apstra.NodeDeployModeDeploy.String(),
links: []link{
{
lagMode: apstra.RackLinkLagModePassive,
groupLabel: "bar",
targetSwitchId: leafIds[0],
targetSwitchIf: "xe-0/0/6",
targetSwitchTf: 1,
tags: []string{"c"},
},
{
lagMode: apstra.RackLinkLagModePassive,
groupLabel: "bar",
targetSwitchId: leafIds[0],
targetSwitchIf: "xe-0/0/7",
targetSwitchTf: 1,
tags: []string{"c"},
},
},
},
testCheckFunc: resource.ComposeAggregateTestCheckFunc([]resource.TestCheckFunc{
resource.TestCheckNoResourceAttr("apstra_datacenter_generic_system.test", "asn"),
resource.TestCheckNoResourceAttr("apstra_datacenter_generic_system.test", "loopback_ipv4"),
resource.TestCheckNoResourceAttr("apstra_datacenter_generic_system.test", "loopback_ipv6"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "deploy_mode", apstra.NodeDeployModeDeploy.String()),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.#", "2"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.group_label", "bar"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.lag_mode", apstra.RackLinkLagModePassive.String()),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.target_switch_if_name", "xe-0/0/6"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.target_switch_if_transform_id", "1"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.tags.#", "1"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.0.tags.0", "c"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.group_label", "bar"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.lag_mode", apstra.RackLinkLagModePassive.String()),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.target_switch_if_name", "xe-0/0/7"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.target_switch_if_transform_id", "1"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.tags.#", "1"),
resource.TestCheckResourceAttr("apstra_datacenter_generic_system.test", "links.1.tags.0", "c"),
}...),
},
{
genericSystem: genericSystem{
//name: "foo",
Expand Down
1 change: 1 addition & 0 deletions docs/resources/datacenter_generic_system.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ resource "apstra_datacenter_generic_system" "example" {
### Optional

- `asn` (Number) AS number of the Generic System
- `deploy_mode` (String) Set the Apstra Deploy Mode for this Generic System. Default: `deploy`
- `external` (Boolean) Set `true` to create an External Generic System
- `hostname` (String) System hostname.
- `loopback_ipv4` (String) IPv4 address of loopback interface in CIDR notation
Expand Down

0 comments on commit 2a29dab

Please sign in to comment.