-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #389 from Juniper/feat/388
Datasource and Resource for Dashboards
- Loading branch information
Showing
16 changed files
with
1,097 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package tfapstra | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/Juniper/apstra-go-sdk/apstra" | ||
"github.com/Juniper/terraform-provider-apstra/apstra/iba" | ||
"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/path" | ||
) | ||
|
||
var _ datasource.DataSourceWithConfigure = &dataSourceIbaDashboard{} | ||
|
||
type dataSourceIbaDashboard struct { | ||
client *apstra.Client | ||
} | ||
|
||
func (o *dataSourceIbaDashboard) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_iba_dashboard" | ||
} | ||
|
||
func (o *dataSourceIbaDashboard) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { | ||
o.client = DataSourceGetClient(ctx, req, resp) | ||
} | ||
|
||
func (o *dataSourceIbaDashboard) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
MarkdownDescription: "This data source provides details of a specific IBA Dashboard in a Blueprint." + | ||
"\n\n" + | ||
"At least one optional attribute is required.", | ||
Attributes: iba.IbaDashboard{}.DataSourceAttributes(), | ||
} | ||
} | ||
|
||
func (o *dataSourceIbaDashboard) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var config iba.IbaDashboard | ||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
bpClient, err := o.client.NewTwoStageL3ClosClient(ctx, apstra.ObjectId(config.BlueprintId.ValueString())) | ||
if err != nil { | ||
if utils.IsApstra404(err) { | ||
resp.Diagnostics.AddError(fmt.Sprintf("blueprint %s not found", | ||
config.BlueprintId), err.Error()) | ||
return | ||
} | ||
resp.Diagnostics.AddError("failed to create blueprint client", err.Error()) | ||
return | ||
} | ||
|
||
var api *apstra.IbaDashboard | ||
switch { | ||
case !config.Name.IsNull(): | ||
api, err = bpClient.GetIbaDashboardByLabel(ctx, config.Name.ValueString()) | ||
if err != nil { | ||
if utils.IsApstra404(err) { | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("name"), | ||
"IBA dashboard not found", | ||
fmt.Sprintf("IBA Dashboard with name %s not found: Error : %q", config.Name, err)) | ||
return | ||
} | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("name"), "Failed reading IBA Dashboard", err.Error(), | ||
) | ||
return | ||
} | ||
case !config.Id.IsNull(): | ||
api, err = bpClient.GetIbaDashboard(ctx, apstra.ObjectId(config.Id.ValueString())) | ||
if err != nil { | ||
if utils.IsApstra404(err) { | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("id"), | ||
"IbaDashboard not found", | ||
fmt.Sprintf("IbaDashboard with ID %s not found", config.Id)) | ||
return | ||
} | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("name"), "Failed reading IBA Dashboard", err.Error(), | ||
) | ||
return | ||
} | ||
} | ||
|
||
config.LoadApiData(ctx, api, &resp.Diagnostics) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
// Set state | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &config)...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package tfapstra | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"github.com/Juniper/apstra-go-sdk/apstra" | ||
testutils "github.com/Juniper/terraform-provider-apstra/apstra/test_utils" | ||
"github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
"testing" | ||
) | ||
|
||
const ( | ||
dataSourceIbaDashboardTemplateByNameHCL = ` | ||
data "apstra_iba_dashboard" "test" { | ||
blueprint_id = "%s" | ||
name = "%s" | ||
} | ||
` | ||
|
||
dataSourceIbaDashboardTemplateByIdHCL = ` | ||
data "apstra_iba_dashboard" "test" { | ||
blueprint_id = "%s" | ||
id = "%s" | ||
} | ||
` | ||
) | ||
|
||
func TestAccDataSourceIbaDashboard(t *testing.T) { | ||
ctx := context.Background() | ||
|
||
bpClient, bpDelete, err := testutils.MakeOrFindBlueprint(ctx, "BPA", testutils.BlueprintA) | ||
|
||
if err != nil { | ||
t.Fatal(errors.Join(err, bpDelete(ctx))) | ||
} | ||
defer func() { | ||
err = bpDelete(ctx) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
}() | ||
|
||
// Set up Widgets | ||
widgetIdA, _, widgetIdB, _, cleanup := testutils.TestWidgetsAB(ctx, t, bpClient) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer func() { | ||
err = cleanup() | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
}() | ||
|
||
data := apstra.IbaDashboardData{ | ||
Description: "Test Dashboard", | ||
Default: false, | ||
Label: "Test Dash", | ||
IbaWidgetGrid: [][]apstra.ObjectId{{widgetIdA, widgetIdB}}, | ||
} | ||
dId, err := bpClient.CreateIbaDashboard(ctx, &data) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer bpClient.DeleteIbaDashboard(ctx, dId) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
// PreCheck: setup, | ||
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, | ||
Steps: []resource.TestStep{ | ||
// Read by ID | ||
{ | ||
Config: insecureProviderConfigHCL + fmt.Sprintf(dataSourceIbaDashboardTemplateByIdHCL, | ||
bpClient.Id().String(), dId.String()), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
resource.TestCheckResourceAttr("data.apstra_iba_dashboard.test", "id", dId.String()), | ||
resource.TestCheckResourceAttr("data.apstra_iba_dashboard.test", "name", data.Label), | ||
resource.TestCheckResourceAttr("data.apstra_iba_dashboard.test", "widget_grid.0.0", widgetIdA.String()), | ||
resource.TestCheckResourceAttr("data.apstra_iba_dashboard.test", "widget_grid.0.1", widgetIdB.String()), | ||
), | ||
}, | ||
// Read by Name | ||
{ | ||
Config: insecureProviderConfigHCL + fmt.Sprintf(dataSourceIbaDashboardTemplateByNameHCL, | ||
bpClient.Id().String(), data.Label), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
resource.TestCheckResourceAttr("data.apstra_iba_dashboard.test", "id", dId.String()), | ||
resource.TestCheckResourceAttr("data.apstra_iba_dashboard.test", "name", data.Label), | ||
resource.TestCheckResourceAttr("data.apstra_iba_dashboard.test", "widget_grid.0.0", widgetIdA.String()), | ||
resource.TestCheckResourceAttr("data.apstra_iba_dashboard.test", "widget_grid.0.1", widgetIdB.String()), | ||
), | ||
}, | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package tfapstra | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/Juniper/apstra-go-sdk/apstra" | ||
"github.com/Juniper/terraform-provider-apstra/apstra/utils" | ||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" | ||
"github.com/hashicorp/terraform-plugin-framework/attr" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
) | ||
|
||
var _ datasource.DataSourceWithConfigure = &dataSourceIbaDashboards{} | ||
|
||
type dataSourceIbaDashboards struct { | ||
client *apstra.Client | ||
} | ||
|
||
func (o *dataSourceIbaDashboards) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_iba_dashboards" | ||
} | ||
|
||
func (o *dataSourceIbaDashboards) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { | ||
o.client = DataSourceGetClient(ctx, req, resp) | ||
} | ||
|
||
func (o *dataSourceIbaDashboards) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
MarkdownDescription: "This data source returns the ID numbers of all IBA Dashboards in a Blueprint.", | ||
Attributes: map[string]schema.Attribute{ | ||
"blueprint_id": schema.StringAttribute{ | ||
MarkdownDescription: "Apstra Blueprint ID. " + | ||
"Used to identify the Blueprint that the IBA Dashboards belongs to.", | ||
Required: true, | ||
Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, | ||
}, | ||
"ids": schema.SetAttribute{ | ||
MarkdownDescription: "A set of Apstra object ID numbers of the IBA Dashboards in the Blueprint.", | ||
Computed: true, | ||
ElementType: types.StringType, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func (o *dataSourceIbaDashboards) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var config struct { | ||
BlueprintId types.String `tfsdk:"blueprint_id"` | ||
Ids types.Set `tfsdk:"ids"` | ||
} | ||
|
||
// get the configuration | ||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
bpClient, err := o.client.NewTwoStageL3ClosClient(ctx, apstra.ObjectId(config.BlueprintId.ValueString())) | ||
if err != nil { | ||
if utils.IsApstra404(err) { | ||
resp.Diagnostics.AddError(fmt.Sprintf("blueprint %s not found", | ||
config.BlueprintId), err.Error()) | ||
return | ||
} | ||
resp.Diagnostics.AddError("failed to create blueprint client", err.Error()) | ||
return | ||
} | ||
|
||
ds, err := bpClient.GetAllIbaDashboards(ctx) | ||
if err != nil { | ||
resp.Diagnostics.AddError("error retrieving IBA Dashboards", err.Error()) | ||
return | ||
} | ||
|
||
ids := make([]attr.Value, len(ds)) | ||
for i, j := range ds { | ||
ids[i] = types.StringValue(j.Id.String()) | ||
} | ||
idSet := types.SetValueMust(types.StringType, ids) | ||
|
||
// create new state object | ||
state := struct { | ||
BlueprintId types.String `tfsdk:"blueprint_id"` | ||
Ids types.Set `tfsdk:"ids"` | ||
}{ | ||
BlueprintId: config.BlueprintId, | ||
Ids: idSet, | ||
} | ||
|
||
// set state | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.