From 9c87de47f2a52e843437de54c673b5302cbe8b93 Mon Sep 17 00:00:00 2001 From: Chris Marget Date: Tue, 5 Nov 2024 11:28:19 -0500 Subject: [PATCH] do not error on incremental config 404 --- ...source_blueprint_device_rendered_config.go | 69 ++++++++----------- ...device_rendered_config_integration_test.go | 36 ++++++---- 2 files changed, 50 insertions(+), 55 deletions(-) diff --git a/apstra/data_source_blueprint_device_rendered_config.go b/apstra/data_source_blueprint_device_rendered_config.go index c741c9b0..3ef115ad 100644 --- a/apstra/data_source_blueprint_device_rendered_config.go +++ b/apstra/data_source_blueprint_device_rendered_config.go @@ -8,9 +8,9 @@ import ( "github.com/Juniper/apstra-go-sdk/apstra" "github.com/Juniper/apstra-go-sdk/apstra/enum" "github.com/Juniper/terraform-provider-apstra/apstra/blueprint" + "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" - "github.com/hashicorp/terraform-plugin-framework/types" ) var ( @@ -46,77 +46,66 @@ func (o *dataSourceBlueprintNodeConfig) Read(ctx context.Context, req datasource return } - addNodeDiag := func(err error) { - var ace apstra.ClientErr - if errors.As(err, &ace) && ace.Type() == apstra.ErrNotfound { - resp.Diagnostics.AddError( - "Not Found", - fmt.Sprintf("Node %s in blueprint %s not found", config.NodeId, config.BlueprintId), - ) - } else { - resp.Diagnostics.AddError("Failed to fetch config", err.Error()) - } - } - - addSysDiag := func(err error) { - var ace apstra.ClientErr - if errors.As(err, &ace) && ace.Type() == apstra.ErrNotfound { - resp.Diagnostics.AddError( - "Not Found", - fmt.Sprintf("System %s in blueprint %s not found", config.SystemId, config.BlueprintId), - ) - } else { - resp.Diagnostics.AddError("Failed to fetch config", err.Error()) - } - } - bpId := apstra.ObjectId(config.BlueprintId.ValueString()) var err error var deployed, staged, incremental string + var ace apstra.ClientErr switch { case !config.NodeId.IsNull(): node := apstra.ObjectId(config.NodeId.ValueString()) deployed, err = o.client.GetNodeRenderedConfig(ctx, bpId, node, enum.RenderedConfigTypeDeployed) if err != nil { - addNodeDiag(err) - return + if !errors.As(err, &ace) || ace.Type() != apstra.ErrNotfound { + resp.Diagnostics.AddError(fmt.Sprintf("failed to fetch deployed configuration for node %s", config.NodeId), err.Error()) + return + } } staged, err = o.client.GetNodeRenderedConfig(ctx, bpId, node, enum.RenderedConfigTypeStaging) if err != nil { - addNodeDiag(err) - return + if !errors.As(err, &ace) || ace.Type() != apstra.ErrNotfound { + resp.Diagnostics.AddError(fmt.Sprintf("failed to fetch staged configuration for node %s", config.NodeId), err.Error()) + return + } } diff, err := o.client.GetNodeRenderedConfigDiff(ctx, bpId, node) if err != nil { - addNodeDiag(err) - return + if !errors.As(err, &ace) || ace.Type() != apstra.ErrNotfound { + resp.Diagnostics.AddError(fmt.Sprintf("failed to fetch incremental configuration for node %s", config.NodeId), err.Error()) + return + } } incremental = diff.Config case !config.SystemId.IsNull(): system := apstra.ObjectId(config.SystemId.ValueString()) deployed, err = o.client.GetSystemRenderedConfig(ctx, bpId, system, enum.RenderedConfigTypeDeployed) if err != nil { - addSysDiag(err) - return + if !errors.As(err, &ace) || ace.Type() != apstra.ErrNotfound { + resp.Diagnostics.AddError(fmt.Sprintf("failed to fetch deployed configuration for system %s", config.SystemId), err.Error()) + return + } } staged, err = o.client.GetSystemRenderedConfig(ctx, bpId, system, enum.RenderedConfigTypeStaging) if err != nil { - addSysDiag(err) - return + if !errors.As(err, &ace) || ace.Type() != apstra.ErrNotfound { + resp.Diagnostics.AddError(fmt.Sprintf("failed to fetch staged configuration for system %s", config.SystemId), err.Error()) + return + } } diff, err := o.client.GetSystemRenderedConfigDiff(ctx, bpId, system) if err != nil { - addSysDiag(err) - return + if !errors.As(err, &ace) || ace.Type() != apstra.ErrNotfound { + resp.Diagnostics.AddError(fmt.Sprintf("failed to fetch incremental configuration for system %s", config.SystemId), err.Error()) + return + } } incremental = diff.Config } - config.DeployedCfg = types.StringValue(deployed) - config.StagedCfg = types.StringValue(staged) - config.Incremental = types.StringValue(incremental) + config.DeployedCfg = utils.StringValueOrNull(ctx, deployed, &resp.Diagnostics) + config.StagedCfg = utils.StringValueOrNull(ctx, staged, &resp.Diagnostics) + config.Incremental = utils.StringValueOrNull(ctx, incremental, &resp.Diagnostics) // set state resp.Diagnostics.Append(resp.State.Set(ctx, &config)...) diff --git a/apstra/data_source_blueprint_device_rendered_config_integration_test.go b/apstra/data_source_blueprint_device_rendered_config_integration_test.go index 9f687e8a..cd478268 100644 --- a/apstra/data_source_blueprint_device_rendered_config_integration_test.go +++ b/apstra/data_source_blueprint_device_rendered_config_integration_test.go @@ -6,6 +6,7 @@ import ( "bufio" "context" "fmt" + "log" "math" "math/rand/v2" "strconv" @@ -147,7 +148,7 @@ func TestAccDatasourceBlueprintDeviceRenderedConfig(t *testing.T) { resource.TestCheckNoResourceAttr("data."+datasourceType+".test", "system_id"), resource.TestCheckResourceAttrSet("data."+datasourceType+".test", "deployed_config"), resource.TestCheckResourceAttrSet("data."+datasourceType+".test", "staged_config"), - resource.TestCheckResourceAttr("data."+datasourceType+".test", "incremental_config", ""), + resource.TestCheckNoResourceAttr("data."+datasourceType+".test", "incremental_config"), resource.TestCheckResourceAttrWith("data."+datasourceType+".test", "deployed_config", atLeast100Lines), resource.TestCheckResourceAttrWith("data."+datasourceType+".test", "staged_config", atLeast100Lines), }, @@ -160,7 +161,7 @@ func TestAccDatasourceBlueprintDeviceRenderedConfig(t *testing.T) { resource.TestCheckResourceAttr("data."+datasourceType+".test", "system_id", sysIds[0].String()), resource.TestCheckResourceAttrSet("data."+datasourceType+".test", "deployed_config"), resource.TestCheckResourceAttrSet("data."+datasourceType+".test", "staged_config"), - resource.TestCheckResourceAttr("data."+datasourceType+".test", "incremental_config", ""), + resource.TestCheckNoResourceAttr("data."+datasourceType+".test", "incremental_config"), resource.TestCheckResourceAttrWith("data."+datasourceType+".test", "deployed_config", atLeast100Lines), resource.TestCheckResourceAttrWith("data."+datasourceType+".test", "staged_config", atLeast100Lines), }, @@ -199,28 +200,32 @@ func TestAccDatasourceBlueprintDeviceRenderedConfig(t *testing.T) { }, } - // bpModificationWg delays modifications to the blueprint until pre-modification tests are complete + // bpModificationWg delays modifications to the blueprint until pre-modification tests are + // complete. Test cases which do not include pre-work contribute to (and delete from) this + // WG. Test cases which include pre-work must wait bpModificationWg := new(sync.WaitGroup) - - // testCaseStartWg ensures that no test case starts begins before all have had a chance - // to pile onto bpModificationWg - testCaseStartWg := new(sync.WaitGroup) - testCaseStartWg.Add(len(testCases)) + for tName, tCase := range testCases { + if tCase.preFunc == nil { + log.Println(tName, "adding to bpModificationWg") + bpModificationWg.Add(1) + } + } for tName, tCase := range testCases { t.Run(tName, func(t *testing.T) { + t.Parallel() + if tCase.config.nodeId == "" && tCase.config.systemId == "" { - testCaseStartWg.Done() + if tCase.preFunc == nil { + log.Println(tName, "done-ing to bpModificationWg") + bpModificationWg.Done() + } t.Skipf("skipping because node has no system assigned") return } - t.Parallel() - if tCase.preFunc == nil { - bpModificationWg.Add(1) - testCaseStartWg.Done() - } else { - testCaseStartWg.Done() + if tCase.preFunc != nil { + log.Printf("%s waiting for bpModificationWg", tName) bpModificationWg.Wait() tCase.preFunc(t, ctx, bp) } @@ -239,6 +244,7 @@ func TestAccDatasourceBlueprintDeviceRenderedConfig(t *testing.T) { }) if tCase.preFunc == nil { + log.Println(tName, "done-ing to bpModificationWg") bpModificationWg.Done() // release test cases which will make changes } })