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

Data source apstra_blueprint_device_rendered_config no error on incremental config 404 #964

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
69 changes: 29 additions & 40 deletions apstra/data_source_blueprint_device_rendered_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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)...)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"bufio"
"context"
"fmt"
"log"
"math"
"math/rand/v2"
"strconv"
Expand Down Expand Up @@ -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),
},
Expand All @@ -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),
},
Expand Down Expand Up @@ -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)
}
Expand All @@ -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
}
})
Expand Down
Loading