From afcc5821297a104274c5bc7f744814b346a98db1 Mon Sep 17 00:00:00 2001 From: Chris Marget Date: Thu, 29 Aug 2024 14:17:35 -0400 Subject: [PATCH 1/6] update `stringSliceOrNull()` helper function to support generic strings --- ...ity_template_interface_integration_test.go | 2 +- ...vity_template_loopback_integration_test.go | 2 +- ...r_connectivity_template_primitives_test.go | 2 +- ...nectivity_template_svi_integration_test.go | 2 +- ...tivity_template_system_integration_test.go | 2 +- ...ource_datacenter_device_allocation_test.go | 2 +- ...atacenter_routing_zone_integration_test.go | 6 +- ...eform_allocation_group_integration_test.go | 2 +- ...eeform_config_template_integration_test.go | 2 +- ...resource_freeform_link_integration_test.go | 2 +- ...ource_freeform_resource_integraion_test.go | 2 +- ...source_freeform_system_integration_test.go | 2 +- apstra/test_helpers_test.go | 64 ++++++++++++++++++- 13 files changed, 77 insertions(+), 15 deletions(-) diff --git a/apstra/resource_datacenter_connectivity_template_interface_integration_test.go b/apstra/resource_datacenter_connectivity_template_interface_integration_test.go index 3329a730..5291d157 100644 --- a/apstra/resource_datacenter_connectivity_template_interface_integration_test.go +++ b/apstra/resource_datacenter_connectivity_template_interface_integration_test.go @@ -88,7 +88,7 @@ func (o resourceDataCenterConnectivityTemplateInterface) render(rType, rName str o.blueprintId, o.name, stringOrNull(o.description), - stringSetOrNull(o.tags), + stringSliceOrNull(o.tags), ipLinks, routingZoneConstraints, virtualNetworkMultiples, diff --git a/apstra/resource_datacenter_connectivity_template_loopback_integration_test.go b/apstra/resource_datacenter_connectivity_template_loopback_integration_test.go index 30f0032a..fc245efa 100644 --- a/apstra/resource_datacenter_connectivity_template_loopback_integration_test.go +++ b/apstra/resource_datacenter_connectivity_template_loopback_integration_test.go @@ -51,7 +51,7 @@ func (o resourceDataCenterConnectivityTemplateLoopback) render(rType, rName stri o.blueprintId, o.name, stringOrNull(o.description), - stringSetOrNull(o.tags), + stringSliceOrNull(o.tags), bgpPeeringIpEndoints, ) } diff --git a/apstra/resource_datacenter_connectivity_template_primitives_test.go b/apstra/resource_datacenter_connectivity_template_primitives_test.go index 33c954f7..42106c6f 100644 --- a/apstra/resource_datacenter_connectivity_template_primitives_test.go +++ b/apstra/resource_datacenter_connectivity_template_primitives_test.go @@ -709,7 +709,7 @@ func (o resourceDataCenterConnectivityTemplatePrimitiveVirtualNetworkMultiple) r fmt.Sprintf(resourceDataCenterConnectivityTemplatePrimitiveVirtualNetworkMultipleHCL, o.name, stringOrNull(o.untaggedVnId), - stringSetOrNull(o.taggedVnIds), + stringSliceOrNull(o.taggedVnIds), ), ) } diff --git a/apstra/resource_datacenter_connectivity_template_svi_integration_test.go b/apstra/resource_datacenter_connectivity_template_svi_integration_test.go index b8a2ea7e..10b743b2 100644 --- a/apstra/resource_datacenter_connectivity_template_svi_integration_test.go +++ b/apstra/resource_datacenter_connectivity_template_svi_integration_test.go @@ -64,7 +64,7 @@ func (o resourceDataCenterConnectivityTemplateSvi) render(rType, rName string) s o.blueprintId, o.name, stringOrNull(o.description), - stringSetOrNull(o.tags), + stringSliceOrNull(o.tags), bgpPeeringIpEndoints, dynamicBgpPeerings, ) diff --git a/apstra/resource_datacenter_connectivity_template_system_integration_test.go b/apstra/resource_datacenter_connectivity_template_system_integration_test.go index b4c8a221..db3c520c 100644 --- a/apstra/resource_datacenter_connectivity_template_system_integration_test.go +++ b/apstra/resource_datacenter_connectivity_template_system_integration_test.go @@ -51,7 +51,7 @@ func (o resourceDataCenterConnectivityTemplateSystem) render(rType, rName string o.blueprintId, o.name, stringOrNull(o.description), - stringSetOrNull(o.tags), + stringSliceOrNull(o.tags), customStaticRoutes, ) } diff --git a/apstra/resource_datacenter_device_allocation_test.go b/apstra/resource_datacenter_device_allocation_test.go index 0d7797a0..1dabeced 100644 --- a/apstra/resource_datacenter_device_allocation_test.go +++ b/apstra/resource_datacenter_device_allocation_test.go @@ -88,7 +88,7 @@ func TestResourceDatacenterDeviceAllocation(t *testing.T) { cidrOrNull(in.loopbackIpv4), cidrOrNull(in.loopbackIpv6), stringOrNull(in.deployMode), - stringSetOrNull(in.tags), + stringSliceOrNull(in.tags), ) } diff --git a/apstra/resource_datacenter_routing_zone_integration_test.go b/apstra/resource_datacenter_routing_zone_integration_test.go index 22a6c302..f50918c5 100644 --- a/apstra/resource_datacenter_routing_zone_integration_test.go +++ b/apstra/resource_datacenter_routing_zone_integration_test.go @@ -53,10 +53,10 @@ func (o testRoutingZone) render(bpId apstra.ObjectId, rType, rName string) strin intPtrOrNull(o.vlan), intPtrOrNull(o.vni), - stringSetOrNull(o.dhcpServers), + stringSliceOrNull(o.dhcpServers), stringOrNull(o.routingPolicy), - stringSetOrNull(o.importRTs), - stringSetOrNull(o.exportRTs), + stringSliceOrNull(o.importRTs), + stringSliceOrNull(o.exportRTs), stringOrNull(o.irbMode), ) } diff --git a/apstra/resource_freeform_allocation_group_integration_test.go b/apstra/resource_freeform_allocation_group_integration_test.go index 07ca8265..91326a1b 100644 --- a/apstra/resource_freeform_allocation_group_integration_test.go +++ b/apstra/resource_freeform_allocation_group_integration_test.go @@ -42,7 +42,7 @@ func (o resourceAllocGroup) render(rType, rName string) string { o.blueprintId, o.name, utils.StringersToFriendlyString(o.groupType), - stringSetOrNull(o.poolIds), + stringSliceOrNull(o.poolIds), ) } diff --git a/apstra/resource_freeform_config_template_integration_test.go b/apstra/resource_freeform_config_template_integration_test.go index 220baeae..9ff209eb 100644 --- a/apstra/resource_freeform_config_template_integration_test.go +++ b/apstra/resource_freeform_config_template_integration_test.go @@ -40,7 +40,7 @@ func (o resourceFreeformConfigTemplate) render(rType, rName string) string { o.blueprintId, o.name, o.text, - stringSetOrNull(o.tags), + stringSliceOrNull(o.tags), ) } diff --git a/apstra/resource_freeform_link_integration_test.go b/apstra/resource_freeform_link_integration_test.go index eb7f5ba5..b48d7888 100644 --- a/apstra/resource_freeform_link_integration_test.go +++ b/apstra/resource_freeform_link_integration_test.go @@ -57,7 +57,7 @@ func (o resourceFreeformLink) render(rType, rName string) string { rType, rName, o.blueprintId, o.name, - stringSetOrNull(o.tags), + stringSliceOrNull(o.tags), o.endpoints[0].SystemId, stringPtrOrNull(o.endpoints[0].Interface.Data.IfName), intPtrOrNull(o.endpoints[0].Interface.Data.TransformationId), diff --git a/apstra/resource_freeform_resource_integraion_test.go b/apstra/resource_freeform_resource_integraion_test.go index 86641854..7d442e4a 100644 --- a/apstra/resource_freeform_resource_integraion_test.go +++ b/apstra/resource_freeform_resource_integraion_test.go @@ -59,7 +59,7 @@ func (o resourceFreeformResource) render(rType, rName string) string { ipNetOrNull(o.ipv4Value), ipNetOrNull(o.ipv6Value), stringOrNull(o.allocatedFrom.String()), - stringSetOrNull(o.assignedTo), + stringSliceOrNull(o.assignedTo), ) } diff --git a/apstra/resource_freeform_system_integration_test.go b/apstra/resource_freeform_system_integration_test.go index 2f15e9a4..3fe9d5cc 100644 --- a/apstra/resource_freeform_system_integration_test.go +++ b/apstra/resource_freeform_system_integration_test.go @@ -50,7 +50,7 @@ func (o resourceFreeformSystem) render(rType, rName string) string { o.hostname, o.systemType, stringOrNull(o.deployMode), - stringSetOrNull(o.tags), + stringSliceOrNull(o.tags), ) } diff --git a/apstra/test_helpers_test.go b/apstra/test_helpers_test.go index dd3ea2de..a66baaa6 100644 --- a/apstra/test_helpers_test.go +++ b/apstra/test_helpers_test.go @@ -138,7 +138,7 @@ func intPtrOrNull[A constraints.Integer](in *A) string { return fmt.Sprintf("%d", *in) } -func stringSetOrNull(in []string) string { +func stringSliceOrNull[S ~string](in []S) string { if len(in) == 0 { return "null" } @@ -407,6 +407,68 @@ func padFormatStr(n, base int) (string, error) { return fmt.Sprintf("%%%d%s", c, baseChar), nil } +func TestStringSliceOrNull(t *testing.T) { + type stringTestCase struct { + s []string + e string + } + + stringTestCases := map[string]stringTestCase{ + "with_strings": { + s: []string{"a", "b", "c"}, + e: `[ "a", "b", "c" ]`, + }, + "empty": { + s: []string{}, + e: "null", + }, + "nil": { + s: nil, + e: "null", + }, + } + + for tName, tCase := range stringTestCases { + t.Run("string_"+tName, func(t *testing.T) { + t.Parallel() + r := stringSliceOrNull(tCase.s) + if tCase.e != r { + t.Fatalf("expected %q, got %q", tCase.e, r) + } + }) + } + + type idTestCase struct { + s []apstra.ObjectId + e string + } + + idTestCases := map[string]idTestCase{ + "with_strings": { + s: []apstra.ObjectId{"a", "b", "c"}, + e: `[ "a", "b", "c" ]`, + }, + "empty": { + s: []apstra.ObjectId{}, + e: "null", + }, + "nil": { + s: nil, + e: "null", + }, + } + + for tName, tCase := range idTestCases { + t.Run("ObjectId_"+tName, func(t *testing.T) { + t.Parallel() + r := stringSliceOrNull(tCase.s) + if tCase.e != r { + t.Fatalf("expected %q, got %q", tCase.e, r) + } + }) + } +} + func TestPadFormatStr(t *testing.T) { type testCase struct { n int From 1be8e821c1cef284563c4d73a30d9b5b06012152 Mon Sep 17 00:00:00 2001 From: bwjuniper Date: Thu, 29 Aug 2024 14:38:53 -0700 Subject: [PATCH 2/6] implement CT assignments to system --- .../data_source_freeform_config_template.go | 13 ++++++++++++ apstra/freeform/config_template.go | 15 ++++++++++++++ apstra/resource_freeform_config_template.go | 20 +++++++++++++++++++ ...eeform_config_template_integration_test.go | 16 ++++++++++++++- docs/data-sources/freeform_config_template.md | 1 + docs/resources/freeform_config_template.md | 1 + go.mod | 4 ++-- go.sum | 2 -- 8 files changed, 67 insertions(+), 5 deletions(-) diff --git a/apstra/data_source_freeform_config_template.go b/apstra/data_source_freeform_config_template.go index fdee8a34..7e6f535a 100644 --- a/apstra/data_source_freeform_config_template.go +++ b/apstra/data_source_freeform_config_template.go @@ -92,6 +92,19 @@ 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)...) } diff --git a/apstra/freeform/config_template.go b/apstra/freeform/config_template.go index 530aa251..134be7fc 100644 --- a/apstra/freeform/config_template.go +++ b/apstra/freeform/config_template.go @@ -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 { @@ -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, + }, } } @@ -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)), + }, + }, } } diff --git a/apstra/resource_freeform_config_template.go b/apstra/resource_freeform_config_template.go index e50b0cd5..31beee9d 100644 --- a/apstra/resource_freeform_config_template.go +++ b/apstra/resource_freeform_config_template.go @@ -78,7 +78,27 @@ 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 + } + + err = bp.UpdateConfigTemplateAssignments(ctx, id, assignments) + if err != nil { + resp.Diagnostics.AddError("error updating ConfigTemplate system Assignments", err.Error()) + return + } + } // set state resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) diff --git a/apstra/resource_freeform_config_template_integration_test.go b/apstra/resource_freeform_config_template_integration_test.go index 9ff209eb..45058e53 100644 --- a/apstra/resource_freeform_config_template_integration_test.go +++ b/apstra/resource_freeform_config_template_integration_test.go @@ -5,6 +5,7 @@ package tfapstra_test import ( "context" "fmt" + "github.com/Juniper/apstra-go-sdk/apstra" "math/rand" "strconv" "testing" @@ -23,6 +24,7 @@ resource %q %q { name = %q text = %q tags = %s + assigned_to = %s } ` ) @@ -32,6 +34,7 @@ type resourceFreeformConfigTemplate struct { name string text string tags []string + assignedTo []apstra.ObjectId } func (o resourceFreeformConfigTemplate) render(rType, rName string) string { @@ -41,6 +44,7 @@ func (o resourceFreeformConfigTemplate) render(rType, rName string) string { o.name, o.text, stringSliceOrNull(o.tags), + stringSliceOrNull(o.assignedTo), ) } @@ -60,6 +64,13 @@ 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)) + } + } + return result } @@ -69,7 +80,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 @@ -95,6 +106,7 @@ func TestResourceFreeformConfigTemplate(t *testing.T) { name: acctest.RandString(6) + ".jinja", text: acctest.RandString(6), tags: randomStrings(rand.Intn(10)+2, 6), + assignedTo: intSysIds, }, }, { @@ -114,6 +126,7 @@ func TestResourceFreeformConfigTemplate(t *testing.T) { name: acctest.RandString(6) + ".jinja", text: acctest.RandString(6), tags: randomStrings(rand.Intn(10)+2, 6), + assignedTo: intSysIds, }, }, { @@ -129,6 +142,7 @@ func TestResourceFreeformConfigTemplate(t *testing.T) { name: acctest.RandString(6) + ".jinja", text: acctest.RandString(6), tags: randomStrings(rand.Intn(10)+2, 6), + assignedTo: intSysIds, }, }, }, diff --git a/docs/data-sources/freeform_config_template.md b/docs/data-sources/freeform_config_template.md index 81f2118e..9a2c581e 100644 --- a/docs/data-sources/freeform_config_template.md +++ b/docs/data-sources/freeform_config_template.md @@ -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 diff --git a/docs/resources/freeform_config_template.md b/docs/resources/freeform_config_template.md index 46b5c33f..b45fa51a 100644 --- a/docs/resources/freeform_config_template.md +++ b/docs/resources/freeform_config_template.md @@ -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 diff --git a/go.mod b/go.mod index 69d6ca30..6ed480ab 100644 --- a/go.mod +++ b/go.mod @@ -2,11 +2,11 @@ module github.com/Juniper/terraform-provider-apstra go 1.22.5 -//replace github.com/Juniper/apstra-go-sdk => ../apstra-go-sdk +replace github.com/Juniper/apstra-go-sdk => ../apstra-go-sdk 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-20240829213205-6eb166eb4bbf 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 diff --git a/go.sum b/go.sum index 66aa716c..8f67bd32 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,6 @@ 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/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= From d1c4ce8a803183010f88964c38c7ec396a3f2ba4 Mon Sep 17 00:00:00 2001 From: bwjuniper Date: Thu, 29 Aug 2024 16:35:01 -0700 Subject: [PATCH 3/6] mo mod tidy after sdk approval --- go.mod | 4 ++-- go.sum | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 6ed480ab..bfad943f 100644 --- a/go.mod +++ b/go.mod @@ -2,11 +2,11 @@ module github.com/Juniper/terraform-provider-apstra go 1.22.5 -replace github.com/Juniper/apstra-go-sdk => ../apstra-go-sdk +//replace github.com/Juniper/apstra-go-sdk => ../apstra-go-sdk require ( github.com/IBM/netaddr v1.5.0 - github.com/Juniper/apstra-go-sdk v0.0.0-20240829213205-6eb166eb4bbf + github.com/Juniper/apstra-go-sdk v0.0.0-20240829233202-c1e3bfdcb4b0 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 diff --git a/go.sum b/go.sum index 8f67bd32..3c7cf83f 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +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-20240829233202-c1e3bfdcb4b0 h1:bAaBKnr+cDHyUch6xL0jznHmBeP4mVvGOYNt6roxNzc= +github.com/Juniper/apstra-go-sdk v0.0.0-20240829233202-c1e3bfdcb4b0/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= From c205ee9970a0ac6a3e9a96530cf042d1c6de66c1 Mon Sep 17 00:00:00 2001 From: bwjuniper Date: Thu, 29 Aug 2024 16:39:03 -0700 Subject: [PATCH 4/6] strange missing link equals that was not deleted from link code --- apstra/freeform/link.go | 1 - 1 file changed, 1 deletion(-) diff --git a/apstra/freeform/link.go b/apstra/freeform/link.go index ee807e7e..3be0c3b0 100644 --- a/apstra/freeform/link.go +++ b/apstra/freeform/link.go @@ -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)) From 9b49b7b17ef8b48061b0b3b3e84e7dc4e8a75337 Mon Sep 17 00:00:00 2001 From: Chris Marget Date: Thu, 29 Aug 2024 23:31:33 -0400 Subject: [PATCH 5/6] WIP: tests still not passing --- .../data_source_freeform_config_template.go | 1 - apstra/freeform/config_template.go | 13 +++++ apstra/resource_freeform_config_template.go | 53 ++++++++++++++++--- ...eeform_config_template_integration_test.go | 6 ++- ...resource_freeform_link_integration_test.go | 1 - 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/apstra/data_source_freeform_config_template.go b/apstra/data_source_freeform_config_template.go index 7e6f535a..d53b33e7 100644 --- a/apstra/data_source_freeform_config_template.go +++ b/apstra/data_source_freeform_config_template.go @@ -93,7 +93,6 @@ func (o *dataSourceFreeformConfigTemplate) Read(ctx context.Context, req datasou } // Read the system assignments - assignments, err := bp.GetConfigTemplateAssignments(ctx, api.Id) if err != nil { resp.Diagnostics.AddError("error reading ConfigTemplate System Assignments", err.Error()) diff --git a/apstra/freeform/config_template.go b/apstra/freeform/config_template.go index 134be7fc..5d9a5ddb 100644 --- a/apstra/freeform/config_template.go +++ b/apstra/freeform/config_template.go @@ -136,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 +} diff --git a/apstra/resource_freeform_config_template.go b/apstra/resource_freeform_config_template.go index 31beee9d..61ff2ea7 100644 --- a/apstra/resource_freeform_config_template.go +++ b/apstra/resource_freeform_config_template.go @@ -137,6 +137,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)...) } @@ -149,6 +161,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 { @@ -169,17 +188,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.UpdateConfigTemplateAssignments(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)...) } diff --git a/apstra/resource_freeform_config_template_integration_test.go b/apstra/resource_freeform_config_template_integration_test.go index 45058e53..819b0817 100644 --- a/apstra/resource_freeform_config_template_integration_test.go +++ b/apstra/resource_freeform_config_template_integration_test.go @@ -69,6 +69,8 @@ func (o resourceFreeformConfigTemplate) testChecks(t testing.TB, rType, rName st for _, assignment := range o.assignedTo { result.append(t, "TestCheckTypeSetElemAttr", "assigned_to.*", string(assignment)) } + } else { + result.append(t, "TestCheckNoResourceAttr", "assigned_to") } return result @@ -91,7 +93,7 @@ func TestResourceFreeformConfigTemplate(t *testing.T) { } testCases := map[string]testCase{ - "start_with_no_tags": { + "start_minimal": { steps: []testStep{ { config: resourceFreeformConfigTemplate{ @@ -118,7 +120,7 @@ func TestResourceFreeformConfigTemplate(t *testing.T) { }, }, }, - "start_with_tags": { + "start_maximal": { steps: []testStep{ { config: resourceFreeformConfigTemplate{ diff --git a/apstra/resource_freeform_link_integration_test.go b/apstra/resource_freeform_link_integration_test.go index b48d7888..0f9cc443 100644 --- a/apstra/resource_freeform_link_integration_test.go +++ b/apstra/resource_freeform_link_integration_test.go @@ -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) From 55ed838b100e6e3c77e686eb7f846d7fe6893343 Mon Sep 17 00:00:00 2001 From: bwjuniper Date: Fri, 30 Aug 2024 12:18:03 -0700 Subject: [PATCH 6/6] update with new sdk method usage and sdk version --- apstra/resource_freeform_config_template.go | 9 +++++++-- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/apstra/resource_freeform_config_template.go b/apstra/resource_freeform_config_template.go index 61ff2ea7..295a1e91 100644 --- a/apstra/resource_freeform_config_template.go +++ b/apstra/resource_freeform_config_template.go @@ -93,7 +93,12 @@ func (o *resourceFreeformConfigTemplate) Create(ctx context.Context, req resourc return } - err = bp.UpdateConfigTemplateAssignments(ctx, id, assignments) + 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 @@ -210,7 +215,7 @@ func (o *resourceFreeformConfigTemplate) Update(ctx context.Context, req resourc return } - err = bp.UpdateConfigTemplateAssignments(ctx, apstra.ObjectId(plan.Id.ValueString()), planAssignments) + err = bp.UpdateConfigTemplateAssignmentsByTemplate(ctx, apstra.ObjectId(plan.Id.ValueString()), planAssignments) if err != nil { resp.Diagnostics.AddError("error updating Resource Assignments", err.Error()) return diff --git a/go.mod b/go.mod index bfad943f..8de1b327 100644 --- a/go.mod +++ b/go.mod @@ -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-20240829233202-c1e3bfdcb4b0 + 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 diff --git a/go.sum b/go.sum index 3c7cf83f..e1ac1252 100644 --- a/go.sum +++ b/go.sum @@ -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-20240829233202-c1e3bfdcb4b0 h1:bAaBKnr+cDHyUch6xL0jznHmBeP4mVvGOYNt6roxNzc= -github.com/Juniper/apstra-go-sdk v0.0.0-20240829233202-c1e3bfdcb4b0/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=