diff --git a/apstra/data_source_freeform_group_generator.go b/apstra/data_source_freeform_resource_group_generator.go similarity index 96% rename from apstra/data_source_freeform_group_generator.go rename to apstra/data_source_freeform_resource_group_generator.go index 3d979ee2..a881b8e8 100644 --- a/apstra/data_source_freeform_group_generator.go +++ b/apstra/data_source_freeform_resource_group_generator.go @@ -23,7 +23,7 @@ type dataSourceFreeformGroupGenerator struct { } func (o *dataSourceFreeformGroupGenerator) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_freeform_group_generator" + resp.TypeName = req.ProviderTypeName + "_freeform_resource_group_generator" } func (o *dataSourceFreeformGroupGenerator) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { @@ -87,7 +87,7 @@ func (o *dataSourceFreeformGroupGenerator) Read(ctx context.Context, req datasou } config.Id = types.StringValue(api.Id.String()) - config.LoadApiData(ctx, api.Data) + config.LoadApiData(ctx, api.Data, &resp.Diagnostics) if resp.Diagnostics.HasError() { return } 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)) diff --git a/apstra/freeform/group_generator.go b/apstra/freeform/resource_group_generator.go similarity index 78% rename from apstra/freeform/group_generator.go rename to apstra/freeform/resource_group_generator.go index c67231a0..25753639 100644 --- a/apstra/freeform/group_generator.go +++ b/apstra/freeform/resource_group_generator.go @@ -2,33 +2,30 @@ package freeform import ( "context" + "regexp" + "github.com/Juniper/apstra-go-sdk/apstra" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" dataSourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" - "regexp" ) type GroupGenerator struct { - BlueprintId types.String `tfsdk:"blueprint_id"` Id types.String `tfsdk:"id"` + BlueprintId types.String `tfsdk:"blueprint_id"` + GroupId types.String `tfsdk:"group_id"` Name types.String `tfsdk:"name"` Scope types.String `tfsdk:"scope"` } func (o GroupGenerator) DataSourceAttributes() map[string]dataSourceSchema.Attribute { return map[string]dataSourceSchema.Attribute{ - "blueprint_id": dataSourceSchema.StringAttribute{ - MarkdownDescription: "Apstra Blueprint ID. Used to identify " + - "the Blueprint where the Group lives.", - Required: true, - Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, - }, "id": dataSourceSchema.StringAttribute{ MarkdownDescription: "Populate this field to look up the Freeform Group Generator by ID. Required when `name` is omitted.", Optional: true, @@ -41,6 +38,16 @@ func (o GroupGenerator) DataSourceAttributes() map[string]dataSourceSchema.Attri }...), }, }, + "blueprint_id": dataSourceSchema.StringAttribute{ + MarkdownDescription: "Apstra Blueprint ID. Used to identify " + + "the Blueprint where the Group lives.", + Required: true, + Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, + }, + "group_id": dataSourceSchema.StringAttribute{ + MarkdownDescription: "Resource Group the Group Generator belongs to.", + Computed: true, + }, "name": dataSourceSchema.StringAttribute{ MarkdownDescription: "Populate this field to look up Group Generator by Name. Required when `id` is omitted.", Optional: true, @@ -57,16 +64,21 @@ func (o GroupGenerator) DataSourceAttributes() map[string]dataSourceSchema.Attri func (o GroupGenerator) ResourceAttributes() map[string]resourceSchema.Attribute { return map[string]resourceSchema.Attribute{ + "id": resourceSchema.StringAttribute{ + MarkdownDescription: "ID of the Group Generator within the Freeform Blueprint.", + Computed: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + }, "blueprint_id": resourceSchema.StringAttribute{ MarkdownDescription: "Apstra Blueprint ID.", Required: true, Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, }, - "id": resourceSchema.StringAttribute{ - MarkdownDescription: "ID of the Group Generator within the Freeform Blueprint.", - Computed: true, - PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + "group_id": resourceSchema.StringAttribute{ + MarkdownDescription: "Resource Group the Group Generator belongs to. Omit to create at the `root` level.", + Optional: true, + Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, }, "name": resourceSchema.StringAttribute{ MarkdownDescription: "Freeform Group Generator name as shown in the Web UI.", @@ -79,22 +91,24 @@ func (o GroupGenerator) ResourceAttributes() map[string]resourceSchema.Attribute }, }, "scope": resourceSchema.StringAttribute{ - MarkdownDescription: "Scope is a graph query which selects target nodes for which Groups should be generated.\n" + - "Example: `node('system', name='target', label=aeq('*prod*'))`", + MarkdownDescription: "Scope is a graph query which selects target nodes for which Group Generators should " + + "be generated.\nExample: `node('system', name='target', label=aeq('*prod*'))`", Required: true, Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, }, } } -func (o *GroupGenerator) Request(_ context.Context) *apstra.FreeformGroupGeneratorData { +func (o *GroupGenerator) Request(_ context.Context, _ *diag.Diagnostics) *apstra.FreeformGroupGeneratorData { return &apstra.FreeformGroupGeneratorData{ - Label: o.Name.ValueString(), - Scope: o.Scope.ValueString(), + ParentId: (*apstra.ObjectId)(o.GroupId.ValueStringPointer()), + Label: o.Name.ValueString(), + Scope: o.Scope.ValueString(), } } -func (o *GroupGenerator) LoadApiData(_ context.Context, in *apstra.FreeformGroupGeneratorData) { +func (o *GroupGenerator) LoadApiData(_ context.Context, in *apstra.FreeformGroupGeneratorData, _ *diag.Diagnostics) { + o.GroupId = types.StringPointerValue((*string)(in.ParentId)) o.Name = types.StringValue(in.Label) o.Scope = types.StringValue(in.Scope) } diff --git a/apstra/resource_freeform_group_generator_integration_test.go b/apstra/resource_freeform_group_generator_integration_test.go deleted file mode 100644 index 59fc50bb..00000000 --- a/apstra/resource_freeform_group_generator_integration_test.go +++ /dev/null @@ -1,125 +0,0 @@ -//go:build integration - -package tfapstra_test - -import ( - "context" - "fmt" - "testing" - - tfapstra "github.com/Juniper/terraform-provider-apstra/apstra" - testutils "github.com/Juniper/terraform-provider-apstra/apstra/test_utils" - "github.com/hashicorp/go-version" - "github.com/hashicorp/terraform-plugin-testing/helper/acctest" - "github.com/hashicorp/terraform-plugin-testing/helper/resource" -) - -const ( - resourceFreeformGroupGeneratorHcl = ` -resource %q %q { - blueprint_id = %q - name = %q - scope = %q - } -` -) - -type resourceFreeformGroupGenerator struct { - blueprintId string - name string - scope string -} - -func (o resourceFreeformGroupGenerator) render(rType, rName string) string { - return fmt.Sprintf(resourceFreeformGroupGeneratorHcl, - rType, rName, - o.blueprintId, - o.name, - o.scope, - ) -} - -func (o resourceFreeformGroupGenerator) testChecks(t testing.TB, rType, rName string) testChecks { - result := newTestChecks(rType + "." + rName) - - // required and computed attributes can always be checked - result.append(t, "TestCheckResourceAttrSet", "id") - result.append(t, "TestCheckResourceAttr", "blueprint_id", o.blueprintId) - result.append(t, "TestCheckResourceAttr", "name", o.name) - result.append(t, "TestCheckResourceAttr", "scope", o.scope) - - return result -} - -func TestResourceFreeformGroupGenerator(t *testing.T) { - ctx := context.Background() - client := testutils.GetTestClient(t, ctx) - apiVersion := version.Must(version.NewVersion(client.ApiVersion())) - - // create a blueprint and a group... - bp, _ := testutils.FfBlueprintC(t, ctx) - - type testStep struct { - config resourceFreeformGroupGenerator - } - - type testCase struct { - apiVersionConstraints version.Constraints - steps []testStep - } - - testCases := map[string]testCase{ - "start_asn_resource_generator": { - steps: []testStep{ - { - config: resourceFreeformGroupGenerator{ - blueprintId: bp.Id().String(), - name: acctest.RandString(6), - scope: "node('system', name='target')", - }, - }, - { - config: resourceFreeformGroupGenerator{ - blueprintId: bp.Id().String(), - name: acctest.RandString(6), - scope: "node('system', deploy_mode='deploy', name='target')", - }, - }, - }, - }, - } - - resourceType := tfapstra.ResourceName(ctx, &tfapstra.ResourceFreeformGroupGenerator) - - for tName, tCase := range testCases { - tName, tCase := tName, tCase - t.Run(tName, func(t *testing.T) { - t.Parallel() - if !tCase.apiVersionConstraints.Check(apiVersion) { - t.Skipf("test case %s requires Apstra %s", tName, tCase.apiVersionConstraints.String()) - } - - steps := make([]resource.TestStep, len(tCase.steps)) - for i, step := range tCase.steps { - config := step.config.render(resourceType, tName) - checks := step.config.testChecks(t, resourceType, tName) - - chkLog := checks.string() - stepName := fmt.Sprintf("test case %q step %d", tName, i+1) - - t.Logf("\n// ------ begin config for %s ------%s// -------- end config for %s ------\n\n", stepName, config, stepName) - t.Logf("\n// ------ begin checks for %s ------\n%s// -------- end checks for %s ------\n\n", stepName, chkLog, stepName) - - steps[i] = resource.TestStep{ - Config: insecureProviderConfigHCL + config, - Check: resource.ComposeAggregateTestCheckFunc(checks.checks...), - } - } - - resource.Test(t, resource.TestCase{ - ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, - Steps: steps, - }) - }) - } -} diff --git a/apstra/resource_freeform_link_integration_test.go b/apstra/resource_freeform_link_integration_test.go index eb7f5ba5..ded3fbed 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) diff --git a/apstra/resource_freeform_resource_generator.go b/apstra/resource_freeform_resource_generator.go index 8e761d97..aa00cb30 100644 --- a/apstra/resource_freeform_resource_generator.go +++ b/apstra/resource_freeform_resource_generator.go @@ -223,7 +223,7 @@ func (o *resourceFreeformResourceGenerator) Delete(ctx context.Context, req reso return } - // Delete Config Template by calling API + // Delete Resource Generator by calling API err = bp.DeleteResourceGenerator(ctx, apstra.ObjectId(state.Id.ValueString())) if err != nil { if utils.IsApstra404(err) { diff --git a/apstra/resource_freeform_group_generator.go b/apstra/resource_freeform_resource_group_generator.go similarity index 95% rename from apstra/resource_freeform_group_generator.go rename to apstra/resource_freeform_resource_group_generator.go index e4eb2792..f51eaa3e 100644 --- a/apstra/resource_freeform_group_generator.go +++ b/apstra/resource_freeform_resource_group_generator.go @@ -24,7 +24,7 @@ type resourceFreeformGroupGenerator struct { } func (o *resourceFreeformGroupGenerator) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_freeform_group_generator" + resp.TypeName = req.ProviderTypeName + "_freeform_resource_group_generator" } func (o *resourceFreeformGroupGenerator) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { @@ -67,7 +67,7 @@ func (o *resourceFreeformGroupGenerator) Create(ctx context.Context, req resourc } // Convert the plan into an API Request - request := plan.Request(ctx) + request := plan.Request(ctx, &resp.Diagnostics) if resp.Diagnostics.HasError() { return } @@ -79,9 +79,8 @@ func (o *resourceFreeformGroupGenerator) Create(ctx context.Context, req resourc return } - plan.Id = types.StringValue(id.String()) - // set state + plan.Id = types.StringValue(id.String()) resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) } @@ -113,7 +112,7 @@ func (o *resourceFreeformGroupGenerator) Read(ctx context.Context, req resource. return } - state.LoadApiData(ctx, api.Data) + state.LoadApiData(ctx, api.Data, &resp.Diagnostics) if resp.Diagnostics.HasError() { return } @@ -151,7 +150,7 @@ func (o *resourceFreeformGroupGenerator) Update(ctx context.Context, req resourc } // Convert the plan into an API Request - request := plan.Request(ctx) + request := plan.Request(ctx, &resp.Diagnostics) if resp.Diagnostics.HasError() { return } @@ -193,7 +192,7 @@ func (o *resourceFreeformGroupGenerator) Delete(ctx context.Context, req resourc return } - // Delete Config Template by calling API + // Delete Resource Generator by calling API err = bp.DeleteGroupGenerator(ctx, apstra.ObjectId(state.Id.ValueString())) if err != nil { if utils.IsApstra404(err) { diff --git a/apstra/resource_freeform_resource_group_generator_integration_test.go b/apstra/resource_freeform_resource_group_generator_integration_test.go new file mode 100644 index 00000000..b451bca8 --- /dev/null +++ b/apstra/resource_freeform_resource_group_generator_integration_test.go @@ -0,0 +1,239 @@ +//go:build integration + +package tfapstra_test + +import ( + "context" + "fmt" + "testing" + + "github.com/Juniper/apstra-go-sdk/apstra" + tfapstra "github.com/Juniper/terraform-provider-apstra/apstra" + testutils "github.com/Juniper/terraform-provider-apstra/apstra/test_utils" + "github.com/hashicorp/go-version" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/stretchr/testify/require" +) + +const ( + resourceFreeformGroupGeneratorHcl = ` +resource %q %q { + blueprint_id = %q + group_id = %s + name = %q + scope = %q + } +` +) + +type resourceFreeformGroupGenerator struct { + blueprintId string + groupId *apstra.ObjectId + name string + scope string +} + +func (o resourceFreeformGroupGenerator) render(rType, rName string) string { + return fmt.Sprintf(resourceFreeformGroupGeneratorHcl, + rType, rName, + o.blueprintId, + stringPtrOrNull(o.groupId), + o.name, + o.scope, + ) +} + +func (o resourceFreeformGroupGenerator) testChecks(t testing.TB, rType, rName string) testChecks { + result := newTestChecks(rType + "." + rName) + + // required and computed attributes can always be checked + result.append(t, "TestCheckResourceAttrSet", "id") + result.append(t, "TestCheckResourceAttr", "blueprint_id", o.blueprintId) + result.append(t, "TestCheckResourceAttr", "name", o.name) + result.append(t, "TestCheckResourceAttr", "scope", o.scope) + + if o.groupId == nil { + result.append(t, "TestCheckNoResourceAttr", "group_id") + } else { + result.append(t, "TestCheckResourceAttr", "group_id", o.groupId.String()) + } + + return result +} + +func TestResourceFreeformGroupGenerator(t *testing.T) { + ctx := context.Background() + client := testutils.GetTestClient(t, ctx) + apiVersion := version.Must(version.NewVersion(client.ApiVersion())) + + resourceGroupCount := 2 + + // create a blueprint + bp := testutils.FfBlueprintA(t, ctx) + + var err error + + resourceGroupIds := make([]apstra.ObjectId, resourceGroupCount) + for i := range resourceGroupCount { + resourceGroupIds[i], err = bp.CreateRaGroup(ctx, &apstra.FreeformRaGroupData{Label: acctest.RandString(6)}) + require.NoError(t, err) + } + + type testStep struct { + config resourceFreeformGroupGenerator + } + + type testCase struct { + apiVersionConstraints version.Constraints + steps []testStep + } + + testCases := map[string]testCase{ + "root": { + steps: []testStep{ + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + }, + }, + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + }, + }, + }, + }, + "group": { + steps: []testStep{ + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + groupId: &resourceGroupIds[0], + }, + }, + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + groupId: &resourceGroupIds[0], + }, + }, + }, + }, + "change_group": { + steps: []testStep{ + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + groupId: &resourceGroupIds[0], + }, + }, + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + groupId: &resourceGroupIds[1], + }, + }, + }, + }, + "root_then_group": { + steps: []testStep{ + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + }, + }, + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + groupId: &resourceGroupIds[1], + }, + }, + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + }, + }, + }, + }, + "group_then_root": { + steps: []testStep{ + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + groupId: &resourceGroupIds[1], + }, + }, + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + }, + }, + { + config: resourceFreeformGroupGenerator{ + blueprintId: bp.Id().String(), + name: acctest.RandString(6), + scope: fmt.Sprintf(`node('system', label='%s', name='target')`, acctest.RandString(6)), + groupId: &resourceGroupIds[1], + }, + }, + }, + }, + } + + resourceType := tfapstra.ResourceName(ctx, &tfapstra.ResourceFreeformGroupGenerator) + + for tName, tCase := range testCases { + tName, tCase := tName, tCase + t.Run(tName, func(t *testing.T) { + t.Parallel() + if !tCase.apiVersionConstraints.Check(apiVersion) { + t.Skipf("test case %s requires Apstra %s", tName, tCase.apiVersionConstraints.String()) + } + + steps := make([]resource.TestStep, len(tCase.steps)) + for i, step := range tCase.steps { + config := step.config.render(resourceType, tName) + checks := step.config.testChecks(t, resourceType, tName) + + chkLog := checks.string() + stepName := fmt.Sprintf("test case %q step %d", tName, i+1) + + t.Logf("\n// ------ begin config for %s ------%s// -------- end config for %s ------\n\n", stepName, config, stepName) + t.Logf("\n// ------ begin checks for %s ------\n%s// -------- end checks for %s ------\n\n", stepName, chkLog, stepName) + + steps[i] = resource.TestStep{ + Config: insecureProviderConfigHCL + config, + Check: resource.ComposeAggregateTestCheckFunc(checks.checks...), + } + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: steps, + }) + }) + } +} diff --git a/apstra/test_helpers_test.go b/apstra/test_helpers_test.go index dd3ea2de..85f63853 100644 --- a/apstra/test_helpers_test.go +++ b/apstra/test_helpers_test.go @@ -56,11 +56,11 @@ func systemIds(ctx context.Context, t *testing.T, bp *apstra.TwoStageL3ClosClien return ids } -func stringPtrOrNull(in *string) string { +func stringPtrOrNull[S ~string](in *S) string { if in == nil { return "null" } - return `"` + *in + `"` + return fmt.Sprintf(`%q`, *in) } func stringOrNull(in string) string { diff --git a/docs/data-sources/freeform_group_generator.md b/docs/data-sources/freeform_resource_group_generator.md similarity index 54% rename from docs/data-sources/freeform_group_generator.md rename to docs/data-sources/freeform_resource_group_generator.md index 66092a82..e00a5790 100644 --- a/docs/data-sources/freeform_group_generator.md +++ b/docs/data-sources/freeform_resource_group_generator.md @@ -1,12 +1,12 @@ --- -page_title: "apstra_freeform_group_generator Data Source - terraform-provider-apstra" +page_title: "apstra_freeform_resource_group_generator Data Source - terraform-provider-apstra" subcategory: "Reference Design: Freeform" description: |- This data source provides details of a specific Freeform Group Generator. At least one optional attribute is required. --- -# apstra_freeform_group_generator (Data Source) +# apstra_freeform_resource_group_generator (Data Source) This data source provides details of a specific Freeform Group Generator. @@ -16,8 +16,8 @@ At least one optional attribute is required. ## Example Usage ```terraform -# This example creates an group Generator within a -# preexisting resource group in a Freeform Blueprint. +# This example creates a Resource Group Generator under a +# Resource Group in a Freeform Blueprint. # # After creating the Group Generator, the data source is invoked to look up # the details. @@ -29,30 +29,31 @@ resource "apstra_freeform_resource_group" "fizz_grp" { } # Create a resource generator scoped to target all systems in the blueprint. -resource "apstra_freeform_group_generator" "test_group_gen" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - name = "test_res_gen" - scope = "node('system', name='target')" +resource "apstra_freeform_resource_group_generator" "test_group_gen" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + group_id = apstra_freeform_resource_group.fizz_grp.id + name = "test_res_gen" + scope = "node('system', name='target')" } -# Invoke the resource generator data source -data "apstra_freeform_group_generator" "test_group_gen" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - id = apstra_freeform_group_generator.test_group_gen.id +# Invoke the resource group generator data source +data "apstra_freeform_resource_group_generator" "test_group_gen" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + id = apstra_freeform_resource_group_generator.test_group_gen.id } # Output the data source so that it prints on screen -output "test_group_generator_out" { - value = data.apstra_freeform_group_generator.test_group_gen +output "test_resource_group_generator_out" { + value = data.apstra_freeform_resource_group_generator.test_group_gen } # The output looks like this: -#test_group_generator_out = { -# "blueprint_id" = "f1b86583-9139-49ed-8a3c-0490253e006e" -# "id" = "wOQS9qZezzRJCgyvxwY" -# "name" = "test_res_gen" -# "scope" = "node('system', name='target')" -#} +# test_resource_group_generator_out = { +# "blueprint_id" = "f1b86583-9139-49ed-8a3c-0490253e006e" +# "id" = "wOQS9qZezzRJCgyvxwY" +# "name" = "test_res_gen" +# "scope" = "node('system', name='target')" +# } ``` @@ -69,5 +70,6 @@ output "test_group_generator_out" { ### Read-Only +- `group_id` (String) Resource Group the Group Generator belongs to. - `scope` (String) Scope is a graph query which selects target nodes for which Groups should be generated. Example: `node('system', name='target', label=aeq('*prod*'))` diff --git a/docs/resources/freeform_group_generator.md b/docs/resources/freeform_group_generator.md deleted file mode 100644 index 653b8960..00000000 --- a/docs/resources/freeform_group_generator.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -page_title: "apstra_freeform_group_generator Resource - terraform-provider-apstra" -subcategory: "Reference Design: Freeform" -description: |- - This resource creates a Group Generator in a Freeform Blueprint. ---- - -# apstra_freeform_group_generator (Resource) - -This resource creates a Group Generator in a Freeform Blueprint. - - -## Example Usage - -```terraform -# This example creates an group Generator within a -# preexisting resource group in a Freeform Blueprint. -# -# After creating the Group Generator, the data source is invoked to look up -# the details. - -# Create a resource group in a preexisting blueprint. -resource "apstra_freeform_resource_group" "fizz_grp" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - name = "fizz_grp" -} - -# Create a resource generator scoped to target all systems in the blueprint. -resource "apstra_freeform_group_generator" "test_group_gen" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - name = "test_res_gen" - scope = "node('system', name='target')" -} - -# Invoke the resource generator data source -data "apstra_freeform_group_generator" "test_group_gen" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - id = apstra_freeform_group_generator.test_group_gen.id -} - -# Output the data source so that it prints on screen -output "test_group_generator_out" { - value = data.apstra_freeform_group_generator.test_group_gen -} - -# The output looks like this: -#test_group_generator_out = { -# "blueprint_id" = "f1b86583-9139-49ed-8a3c-0490253e006e" -# "id" = "wOQS9qZezzRJCgyvxwY" -# "name" = "test_res_gen" -# "scope" = "node('system', name='target')" -#} -``` - - -## Schema - -### Required - -- `blueprint_id` (String) Apstra Blueprint ID. -- `name` (String) Freeform Group Generator name as shown in the Web UI. -- `scope` (String) Scope is a graph query which selects target nodes for which Groups should be generated. -Example: `node('system', name='target', label=aeq('*prod*'))` - -### Read-Only - -- `id` (String) ID of the Group Generator within the Freeform Blueprint. - - - diff --git a/docs/resources/freeform_resource_group_generator.md b/docs/resources/freeform_resource_group_generator.md new file mode 100644 index 00000000..10effc06 --- /dev/null +++ b/docs/resources/freeform_resource_group_generator.md @@ -0,0 +1,75 @@ +--- +page_title: "apstra_freeform_resource_group_generator Resource - terraform-provider-apstra" +subcategory: "Reference Design: Freeform" +description: |- + This resource creates a Group Generator in a Freeform Blueprint. +--- + +# apstra_freeform_resource_group_generator (Resource) + +This resource creates a Group Generator in a Freeform Blueprint. + + +## Example Usage + +```terraform +# This example creates a Resource Group Generator under a +# Resource Group in a Freeform Blueprint. +# +# After creating the Group Generator, the data source is invoked to look up +# the details. + +# Create a resource group in a preexisting blueprint. +resource "apstra_freeform_resource_group" "fizz_grp" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + name = "fizz_grp" +} + +# Create a resource generator scoped to target all systems in the blueprint. +resource "apstra_freeform_resource_group_generator" "test_group_gen" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + group_id = apstra_freeform_resource_group.fizz_grp.id + name = "test_res_gen" + scope = "node('system', name='target')" +} + +# Invoke the resource group generator data source +data "apstra_freeform_resource_group_generator" "test_group_gen" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + id = apstra_freeform_resource_group_generator.test_group_gen.id +} + +# Output the data source so that it prints on screen +output "test_resource_group_generator_out" { + value = data.apstra_freeform_resource_group_generator.test_group_gen +} + +# The output looks like this: +# test_resource_group_generator_out = { +# "blueprint_id" = "f1b86583-9139-49ed-8a3c-0490253e006e" +# "id" = "wOQS9qZezzRJCgyvxwY" +# "name" = "test_res_gen" +# "scope" = "node('system', name='target')" +# } +``` + + +## Schema + +### Required + +- `blueprint_id` (String) Apstra Blueprint ID. +- `name` (String) Freeform Group Generator name as shown in the Web UI. +- `scope` (String) Scope is a graph query which selects target nodes for which Group Generators should be generated. +Example: `node('system', name='target', label=aeq('*prod*'))` + +### Optional + +- `group_id` (String) Resource Group the Group Generator belongs to. Omit to create at the `root` level. + +### Read-Only + +- `id` (String) ID of the Group Generator within the Freeform Blueprint. + + + diff --git a/examples/data-sources/apstra_freeform_group_generator/example.tf b/examples/data-sources/apstra_freeform_group_generator/example.tf deleted file mode 100644 index 9a812d61..00000000 --- a/examples/data-sources/apstra_freeform_group_generator/example.tf +++ /dev/null @@ -1,38 +0,0 @@ -# This example creates an group Generator within a -# preexisting resource group in a Freeform Blueprint. -# -# After creating the Group Generator, the data source is invoked to look up -# the details. - -# Create a resource group in a preexisting blueprint. -resource "apstra_freeform_resource_group" "fizz_grp" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - name = "fizz_grp" -} - -# Create a resource generator scoped to target all systems in the blueprint. -resource "apstra_freeform_group_generator" "test_group_gen" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - name = "test_res_gen" - scope = "node('system', name='target')" -} - -# Invoke the resource generator data source -data "apstra_freeform_group_generator" "test_group_gen" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - id = apstra_freeform_group_generator.test_group_gen.id -} - -# Output the data source so that it prints on screen -output "test_group_generator_out" { - value = data.apstra_freeform_group_generator.test_group_gen -} - -# The output looks like this: -#test_group_generator_out = { -# "blueprint_id" = "f1b86583-9139-49ed-8a3c-0490253e006e" -# "id" = "wOQS9qZezzRJCgyvxwY" -# "name" = "test_res_gen" -# "scope" = "node('system', name='target')" -#} - diff --git a/examples/data-sources/apstra_freeform_resource_group_generator/example.tf b/examples/data-sources/apstra_freeform_resource_group_generator/example.tf new file mode 100644 index 00000000..aac9d850 --- /dev/null +++ b/examples/data-sources/apstra_freeform_resource_group_generator/example.tf @@ -0,0 +1,39 @@ +# This example creates a Resource Group Generator under a +# Resource Group in a Freeform Blueprint. +# +# After creating the Group Generator, the data source is invoked to look up +# the details. + +# Create a resource group in a preexisting blueprint. +resource "apstra_freeform_resource_group" "fizz_grp" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + name = "fizz_grp" +} + +# Create a resource generator scoped to target all systems in the blueprint. +resource "apstra_freeform_resource_group_generator" "test_group_gen" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + group_id = apstra_freeform_resource_group.fizz_grp.id + name = "test_res_gen" + scope = "node('system', name='target')" +} + +# Invoke the resource group generator data source +data "apstra_freeform_resource_group_generator" "test_group_gen" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + id = apstra_freeform_resource_group_generator.test_group_gen.id +} + +# Output the data source so that it prints on screen +output "test_resource_group_generator_out" { + value = data.apstra_freeform_resource_group_generator.test_group_gen +} + +# The output looks like this: +# test_resource_group_generator_out = { +# "blueprint_id" = "f1b86583-9139-49ed-8a3c-0490253e006e" +# "id" = "wOQS9qZezzRJCgyvxwY" +# "name" = "test_res_gen" +# "scope" = "node('system', name='target')" +# } + diff --git a/examples/resources/apstra_freeform_group_generator/example.tf b/examples/resources/apstra_freeform_group_generator/example.tf deleted file mode 100644 index 9a812d61..00000000 --- a/examples/resources/apstra_freeform_group_generator/example.tf +++ /dev/null @@ -1,38 +0,0 @@ -# This example creates an group Generator within a -# preexisting resource group in a Freeform Blueprint. -# -# After creating the Group Generator, the data source is invoked to look up -# the details. - -# Create a resource group in a preexisting blueprint. -resource "apstra_freeform_resource_group" "fizz_grp" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - name = "fizz_grp" -} - -# Create a resource generator scoped to target all systems in the blueprint. -resource "apstra_freeform_group_generator" "test_group_gen" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - name = "test_res_gen" - scope = "node('system', name='target')" -} - -# Invoke the resource generator data source -data "apstra_freeform_group_generator" "test_group_gen" { - blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" - id = apstra_freeform_group_generator.test_group_gen.id -} - -# Output the data source so that it prints on screen -output "test_group_generator_out" { - value = data.apstra_freeform_group_generator.test_group_gen -} - -# The output looks like this: -#test_group_generator_out = { -# "blueprint_id" = "f1b86583-9139-49ed-8a3c-0490253e006e" -# "id" = "wOQS9qZezzRJCgyvxwY" -# "name" = "test_res_gen" -# "scope" = "node('system', name='target')" -#} - diff --git a/examples/resources/apstra_freeform_resource_group_generator/example.tf b/examples/resources/apstra_freeform_resource_group_generator/example.tf new file mode 100644 index 00000000..aac9d850 --- /dev/null +++ b/examples/resources/apstra_freeform_resource_group_generator/example.tf @@ -0,0 +1,39 @@ +# This example creates a Resource Group Generator under a +# Resource Group in a Freeform Blueprint. +# +# After creating the Group Generator, the data source is invoked to look up +# the details. + +# Create a resource group in a preexisting blueprint. +resource "apstra_freeform_resource_group" "fizz_grp" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + name = "fizz_grp" +} + +# Create a resource generator scoped to target all systems in the blueprint. +resource "apstra_freeform_resource_group_generator" "test_group_gen" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + group_id = apstra_freeform_resource_group.fizz_grp.id + name = "test_res_gen" + scope = "node('system', name='target')" +} + +# Invoke the resource group generator data source +data "apstra_freeform_resource_group_generator" "test_group_gen" { + blueprint_id = "f1b86583-9139-49ed-8a3c-0490253e006e" + id = apstra_freeform_resource_group_generator.test_group_gen.id +} + +# Output the data source so that it prints on screen +output "test_resource_group_generator_out" { + value = data.apstra_freeform_resource_group_generator.test_group_gen +} + +# The output looks like this: +# test_resource_group_generator_out = { +# "blueprint_id" = "f1b86583-9139-49ed-8a3c-0490253e006e" +# "id" = "wOQS9qZezzRJCgyvxwY" +# "name" = "test_res_gen" +# "scope" = "node('system', name='target')" +# } + diff --git a/go.mod b/go.mod index ad04de40..34a0207c 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-20240828195058-e7a28edd78dd + github.com/Juniper/apstra-go-sdk v0.0.0-20240830010414-20bd6839d500 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 6e1e8397..3db95f38 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-20240828195058-e7a28edd78dd h1:aHNvAvImPwBDCFTTC6CaMJt5VvPSQGpfJaRrsScG9zs= -github.com/Juniper/apstra-go-sdk v0.0.0-20240828195058-e7a28edd78dd/go.mod h1:cSUzaIIQzZysIVKgJnt2/jO2EKeAB60Xgbx8yBGwJ8Y= +github.com/Juniper/apstra-go-sdk v0.0.0-20240830010414-20bd6839d500 h1:vvvqUWUrgB9U8wbWmsrOjbJLQm2iMLpEikZfZJtfy4Q= +github.com/Juniper/apstra-go-sdk v0.0.0-20240830010414-20bd6839d500/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=