Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement CT assignments to system #837

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
12 changes: 12 additions & 0 deletions apstra/data_source_freeform_config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ func (o *dataSourceFreeformConfigTemplate) Read(ctx context.Context, req datasou
return
}

// Read the system assignments
assignments, err := bp.GetConfigTemplateAssignments(ctx, api.Id)
if err != nil {
resp.Diagnostics.AddError("error reading ConfigTemplate System Assignments", err.Error())
return
}

config.AssignedTo = utils.SetValueOrNull(ctx, types.StringType, assignments, &resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
}

// Set state
resp.Diagnostics.Append(resp.State.Set(ctx, &config)...)
}
Expand Down
28 changes: 28 additions & 0 deletions apstra/freeform/config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type ConfigTemplate struct {
Name types.String `tfsdk:"name"`
Text types.String `tfsdk:"text"`
Tags types.Set `tfsdk:"tags"`
AssignedTo types.Set `tfsdk:"assigned_to"`
}

func (o ConfigTemplate) DataSourceAttributes() map[string]dataSourceSchema.Attribute {
Expand Down Expand Up @@ -61,6 +62,11 @@ func (o ConfigTemplate) DataSourceAttributes() map[string]dataSourceSchema.Attri
ElementType: types.StringType,
Computed: true,
},
"assigned_to": dataSourceSchema.SetAttribute{
MarkdownDescription: "Set of System IDs to which the ConfigTemplate is assigned",
ElementType: types.StringType,
Computed: true,
},
}
}

Expand Down Expand Up @@ -99,6 +105,15 @@ func (o ConfigTemplate) ResourceAttributes() map[string]resourceSchema.Attribute
setvalidator.ValueStringsAre(stringvalidator.LengthAtLeast(1)),
},
},
"assigned_to": resourceSchema.SetAttribute{
MarkdownDescription: "Set of System IDs to which the ConfigTemplate is assigned",
ElementType: types.StringType,
Optional: true,
Validators: []validator.Set{
setvalidator.SizeAtLeast(1),
setvalidator.ValueStringsAre(stringvalidator.LengthAtLeast(1)),
},
},
}
}

Expand All @@ -121,3 +136,16 @@ func (o *ConfigTemplate) LoadApiData(ctx context.Context, in *apstra.ConfigTempl
o.Text = types.StringValue(in.Text)
o.Tags = utils.SetValueOrNull(ctx, types.StringType, in.Tags, diags) // safe to ignore diagnostic here
}

func (o ConfigTemplate) NeedsUpdate(state ConfigTemplate) bool {
switch {
case !o.Name.Equal(state.Name):
return true
case !o.Text.Equal(state.Text):
return true
case !o.Tags.Equal(state.Tags):
return true
}

return false
}
1 change: 0 additions & 1 deletion apstra/freeform/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ func (o *Link) LoadApiData(ctx context.Context, in *apstra.FreeformLinkData, dia
}

o.Speed = types.StringValue(string(in.Speed))
o.Type = types.StringValue(in.Type.String())
o.Name = types.StringValue(in.Label)
o.Endpoints = newFreeformEndpointMap(ctx, in.Endpoints, diags) // safe to ignore diagnostic here
o.AggregateLinkId = types.StringPointerValue((*string)(in.AggregateLinkId))
Expand Down
78 changes: 70 additions & 8 deletions apstra/resource_freeform_config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,32 @@ func (o *resourceFreeformConfigTemplate) Create(ctx context.Context, req resourc
return
}

// record the id and provisionally set the state
plan.Id = types.StringValue(id.String())
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}

// set the CT system assignments, if any
if !plan.AssignedTo.IsNull() {
var assignments []apstra.ObjectId
resp.Diagnostics.Append(plan.AssignedTo.ElementsAs(ctx, &assignments, false)...)
if resp.Diagnostics.HasError() {
return
}

updateRequest := make(map[apstra.ObjectId]*apstra.ObjectId, len(assignments))
for _, assignment := range assignments {
updateRequest[assignment] = &id
}

err = bp.UpdateConfigTemplateAssignments(ctx, updateRequest)
if err != nil {
resp.Diagnostics.AddError("error updating ConfigTemplate system Assignments", err.Error())
return
}
}

// set state
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
Expand Down Expand Up @@ -117,6 +142,18 @@ func (o *resourceFreeformConfigTemplate) Read(ctx context.Context, req resource.
return
}

// Read the system assignments
assignments, err := bp.GetConfigTemplateAssignments(ctx, api.Id)
if err != nil {
resp.Diagnostics.AddError("error reading ConfigTemplate System Assignments", err.Error())
return
}

state.AssignedTo = utils.SetValueOrNull(ctx, types.StringType, assignments, &resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
}

// Set state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
Expand All @@ -129,6 +166,13 @@ func (o *resourceFreeformConfigTemplate) Update(ctx context.Context, req resourc
return
}

// Get state values
var state freeform.ConfigTemplate
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

// get a client for the Freeform reference design
bp, err := o.getBpClientFunc(ctx, plan.BlueprintId.ValueString())
if err != nil {
Expand All @@ -149,17 +193,35 @@ func (o *resourceFreeformConfigTemplate) Update(ctx context.Context, req resourc
return
}

request := plan.Request(ctx, &resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
if plan.NeedsUpdate(state) {
request := plan.Request(ctx, &resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
}

// Update Config Template
err = bp.UpdateConfigTemplate(ctx, apstra.ObjectId(plan.Id.ValueString()), request)
if err != nil {
resp.Diagnostics.AddError("error updating Config Template", err.Error())
return
}
}

// Update Config Template
err = bp.UpdateConfigTemplate(ctx, apstra.ObjectId(plan.Id.ValueString()), request)
if err != nil {
resp.Diagnostics.AddError("error updating Config Template", err.Error())
return
// update the assignments if necessary
if !plan.AssignedTo.Equal(state.AssignedTo) {
var planAssignments []apstra.ObjectId
resp.Diagnostics.Append(plan.AssignedTo.ElementsAs(ctx, &planAssignments, false)...)
if resp.Diagnostics.HasError() {
return
}

err = bp.UpdateConfigTemplateAssignmentsByTemplate(ctx, apstra.ObjectId(plan.Id.ValueString()), planAssignments)
if err != nil {
resp.Diagnostics.AddError("error updating Resource Assignments", err.Error())
return
}
}

// set state
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}
Expand Down
22 changes: 19 additions & 3 deletions apstra/resource_freeform_config_template_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package tfapstra_test
import (
"context"
"fmt"
"github.com/Juniper/apstra-go-sdk/apstra"
"math/rand"
"strconv"
"testing"
Expand All @@ -23,6 +24,7 @@ resource %q %q {
name = %q
text = %q
tags = %s
assigned_to = %s
}
`
)
Expand All @@ -32,6 +34,7 @@ type resourceFreeformConfigTemplate struct {
name string
text string
tags []string
assignedTo []apstra.ObjectId
}

func (o resourceFreeformConfigTemplate) render(rType, rName string) string {
Expand All @@ -41,6 +44,7 @@ func (o resourceFreeformConfigTemplate) render(rType, rName string) string {
o.name,
o.text,
stringSliceOrNull(o.tags),
stringSliceOrNull(o.assignedTo),
)
}

Expand All @@ -60,6 +64,15 @@ func (o resourceFreeformConfigTemplate) testChecks(t testing.TB, rType, rName st
}
}

if len(o.assignedTo) > 0 {
result.append(t, "TestCheckResourceAttr", "assigned_to.#", strconv.Itoa(len(o.assignedTo)))
for _, assignment := range o.assignedTo {
result.append(t, "TestCheckTypeSetElemAttr", "assigned_to.*", string(assignment))
}
} else {
result.append(t, "TestCheckNoResourceAttr", "assigned_to")
}

return result
}

Expand All @@ -69,7 +82,7 @@ func TestResourceFreeformConfigTemplate(t *testing.T) {
apiVersion := version.Must(version.NewVersion(client.ApiVersion()))

// create a blueprint
bp := testutils.FfBlueprintA(t, ctx)
bp, intSysIds, _ := testutils.FfBlueprintB(t, ctx, 3, 0)

type testStep struct {
config resourceFreeformConfigTemplate
Expand All @@ -80,7 +93,7 @@ func TestResourceFreeformConfigTemplate(t *testing.T) {
}

testCases := map[string]testCase{
"start_with_no_tags": {
"start_minimal": {
steps: []testStep{
{
config: resourceFreeformConfigTemplate{
Expand All @@ -95,6 +108,7 @@ func TestResourceFreeformConfigTemplate(t *testing.T) {
name: acctest.RandString(6) + ".jinja",
text: acctest.RandString(6),
tags: randomStrings(rand.Intn(10)+2, 6),
assignedTo: intSysIds,
},
},
{
Expand All @@ -106,14 +120,15 @@ func TestResourceFreeformConfigTemplate(t *testing.T) {
},
},
},
"start_with_tags": {
"start_maximal": {
steps: []testStep{
{
config: resourceFreeformConfigTemplate{
blueprintId: bp.Id().String(),
name: acctest.RandString(6) + ".jinja",
text: acctest.RandString(6),
tags: randomStrings(rand.Intn(10)+2, 6),
assignedTo: intSysIds,
},
},
{
Expand All @@ -129,6 +144,7 @@ func TestResourceFreeformConfigTemplate(t *testing.T) {
name: acctest.RandString(6) + ".jinja",
text: acctest.RandString(6),
tags: randomStrings(rand.Intn(10)+2, 6),
assignedTo: intSysIds,
},
},
},
Expand Down
1 change: 0 additions & 1 deletion apstra/resource_freeform_link_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ func (o resourceFreeformLink) testChecks(t testing.TB, rType, rName string, ipAl

// required and computed attributes can always be checked
result.append(t, "TestCheckResourceAttrSet", "id")
result.append(t, "TestCheckResourceAttr", "type", apstra.FFLinkTypeEthernet.String())
result.append(t, "TestCheckNoResourceAttr", "aggregate_link_id")
result.append(t, "TestCheckResourceAttr", "blueprint_id", o.blueprintId)
result.append(t, "TestCheckResourceAttr", "name", o.name)
Expand Down
1 change: 1 addition & 0 deletions docs/data-sources/freeform_config_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ data "apstra_freeform_config_template" "interfaces" {

### Read-Only

- `assigned_to` (Set of String) Set of System IDs to which the ConfigTemplate is assigned
- `tags` (Set of String) Set of Tag labels
- `text` (String) Configuration Jinja2 template text
1 change: 1 addition & 0 deletions docs/resources/freeform_config_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ interfaces {

### Optional

- `assigned_to` (Set of String) Set of System IDs to which the ConfigTemplate is assigned
- `tags` (Set of String) Set of Tag labels

### Read-Only
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ go 1.22.5

require (
github.com/IBM/netaddr v1.5.0
github.com/Juniper/apstra-go-sdk v0.0.0-20240827214729-1f8d4ab953cf
github.com/Juniper/apstra-go-sdk v0.0.0-20240830190524-b13fda0b2a3a
github.com/chrismarget-j/go-licenses v0.0.0-20240224210557-f22f3e06d3d4
github.com/google/go-cmp v0.6.0
github.com/hashicorp/go-version v1.7.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
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-20240827214729-1f8d4ab953cf h1:bAOJtOEAk0JSDCpTBwWMJg+2a3A2YoflVWUPi7gKonQ=
github.com/Juniper/apstra-go-sdk v0.0.0-20240827214729-1f8d4ab953cf/go.mod h1:cSUzaIIQzZysIVKgJnt2/jO2EKeAB60Xgbx8yBGwJ8Y=
github.com/Juniper/apstra-go-sdk v0.0.0-20240830190524-b13fda0b2a3a h1:XKSJTw1oVxF8uOsLmSr3yhb//9K3+mqqwJNxebyvXeI=
github.com/Juniper/apstra-go-sdk v0.0.0-20240830190524-b13fda0b2a3a/go.mod h1:cSUzaIIQzZysIVKgJnt2/jO2EKeAB60Xgbx8yBGwJ8Y=
github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0=
github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
Expand Down
Loading