-
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.
Add support for iba widget data source
- Loading branch information
1 parent
98b7ca6
commit 661b25d
Showing
12 changed files
with
587 additions
and
3 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,59 @@ | ||
package blueprint | ||
|
||
import ( | ||
"context" | ||
"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" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
) | ||
|
||
type IbaWidget struct { | ||
BlueprintId types.String `tfsdk:"blueprint_id"` | ||
Id types.String `tfsdk:"id"` | ||
Label types.String `tfsdk:"label"` | ||
Description types.String `tfsdk:"description"` | ||
} | ||
|
||
func (o IbaWidget) DataSourceAttributes() map[string]dataSourceSchema.Attribute { | ||
return map[string]dataSourceSchema.Attribute{ | ||
"blueprint_id": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Apstra Blueprint ID. Used to identify the Blueprint that the IBA Widget belongs to.", | ||
Required: true, | ||
Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, | ||
}, | ||
"id": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Populate this field to look up a IBA Widget by ID. Required when `name` is omitted.", | ||
Optional: true, | ||
Computed: true, | ||
Validators: []validator.String{ | ||
stringvalidator.LengthAtLeast(1), | ||
stringvalidator.ExactlyOneOf(path.Expressions{ | ||
path.MatchRelative(), | ||
path.MatchRoot("label"), | ||
}...), | ||
}, | ||
}, | ||
"label": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Populate this field to look up a IBA Widget by name. Required when `id` is omitted.", | ||
Optional: true, | ||
Computed: true, | ||
Validators: []validator.String{ | ||
stringvalidator.LengthAtLeast(1), | ||
}, | ||
}, | ||
"description": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Description of the IBA Widget", | ||
Computed: true, | ||
}, | ||
} | ||
} | ||
|
||
func (o *IbaWidget) LoadApiData(ctx context.Context, in *apstra.IbaWidget, _ *diag.Diagnostics) { | ||
o.Id = types.StringValue(in.Id.String()) | ||
o.Label = types.StringValue(in.Data.Label) | ||
o.Description = types.StringValue(in.Data.Description) | ||
} |
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/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/path" | ||
) | ||
|
||
var _ datasource.DataSourceWithConfigure = &dataSourceDatacenterIbaWidget{} | ||
|
||
type dataSourceDatacenterIbaWidget struct { | ||
client *apstra.Client | ||
} | ||
|
||
func (o *dataSourceDatacenterIbaWidget) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_datacenter_iba_widget" | ||
} | ||
|
||
func (o *dataSourceDatacenterIbaWidget) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { | ||
o.client = DataSourceGetClient(ctx, req, resp) | ||
} | ||
|
||
func (o *dataSourceDatacenterIbaWidget) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
MarkdownDescription: "This data source provides details of a specific IBA Widget in a Blueprint." + | ||
"\n\n" + | ||
"At least one optional attribute is required.", | ||
Attributes: blueprint.IbaWidget{}.DataSourceAttributes(), | ||
} | ||
} | ||
|
||
func (o *dataSourceDatacenterIbaWidget) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var config blueprint.IbaWidget | ||
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.IbaWidget | ||
switch { | ||
case !config.Label.IsNull(): | ||
api, err = bpClient.GetIbaWidgetByLabel(ctx, config.Label.ValueString()) | ||
if err != nil { | ||
if utils.IsApstra404(err) { | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("name"), | ||
"IBA widget not found", | ||
fmt.Sprintf("IBA Widget with label %s not found", config.Label)) | ||
return | ||
} | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("name"), "Failed reading IBA Widget", err.Error(), | ||
) | ||
return | ||
} | ||
case !config.Id.IsNull(): | ||
api, err = bpClient.GetIbaWidget(ctx, apstra.ObjectId(config.Id.ValueString())) | ||
if err != nil { | ||
if utils.IsApstra404(err) { | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("id"), | ||
"IbaWidget not found", | ||
fmt.Sprintf("IbaWidget with ID %s not found", config.Id)) | ||
return | ||
} | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("name"), "Failed reading IBA Widgett", 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,81 @@ | ||
package tfapstra | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
testutils "github.com/Juniper/terraform-provider-apstra/apstra/test_utils" | ||
"github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
"testing" | ||
) | ||
|
||
const ( | ||
dataSourceDatacenterIbaWidgetTemplateByNameHCL = ` | ||
data "apstra_datacenter_iba_widget" "test" { | ||
blueprint_id = "%s" | ||
label = "%s" | ||
} | ||
` | ||
|
||
dataSourceDatacenterIbaWidgetTemplateByIdHCL = ` | ||
data "apstra_datacenter_iba_widget" "test" { | ||
blueprint_id = "%s" | ||
id = "%s" | ||
} | ||
` | ||
) | ||
|
||
func TestAccDataSourceDatacenterIbaWidget(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, widgetDataA, _, _, cleanup := testutils.TestWidgetsAB(ctx, t, bpClient) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer func() { | ||
err = cleanup() | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
}() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
// PreCheck: setup, | ||
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, | ||
Steps: []resource.TestStep{ | ||
// Read by ID | ||
{ | ||
Config: insecureProviderConfigHCL + fmt.Sprintf(dataSourceDatacenterIbaWidgetTemplateByIdHCL, | ||
string(bpClient.Id()), string(widgetIdA)), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
resource.TestCheckResourceAttr("data.apstra_datacenter_iba_widget.test", "id", widgetIdA.String()), | ||
resource.TestCheckResourceAttr("data.apstra_datacenter_iba_widget.test", "label", | ||
widgetDataA.Label), | ||
), | ||
}, | ||
// Read by Name | ||
{ | ||
Config: insecureProviderConfigHCL + fmt.Sprintf(dataSourceDatacenterIbaWidgetTemplateByNameHCL, | ||
string(bpClient.Id()), widgetDataA.Label), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
resource.TestCheckResourceAttr("data.apstra_datacenter_iba_widget.test", "id", widgetIdA.String()), | ||
resource.TestCheckResourceAttr("data.apstra_datacenter_iba_widget.test", "label", | ||
widgetDataA.Label), | ||
), | ||
}, | ||
}, | ||
}) | ||
} |
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,98 @@ | ||
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/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 = &dataSourceDatacenterIbaWidgets{} | ||
|
||
type dataSourceDatacenterIbaWidgets struct { | ||
client *apstra.Client | ||
} | ||
|
||
func (o *dataSourceDatacenterIbaWidgets) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_datacenter_iba_widgets" | ||
} | ||
|
||
func (o *dataSourceDatacenterIbaWidgets) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { | ||
o.client = DataSourceGetClient(ctx, req, resp) | ||
} | ||
|
||
func (o *dataSourceDatacenterIbaWidgets) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
MarkdownDescription: "This data source returns the ID numbers of all IBA Widgets in a Blueprint.", | ||
Attributes: map[string]schema.Attribute{ | ||
"blueprint_id": schema.StringAttribute{ | ||
MarkdownDescription: "Apstra Blueprint ID. " + | ||
"Used to identify the Blueprint that the IBA Widgets belongs to.", | ||
Required: true, | ||
Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, | ||
}, | ||
"ids": schema.SetAttribute{ | ||
MarkdownDescription: "A set of Apstra object ID numbers representing the IBA Widgets in the blueprint.", | ||
Computed: true, | ||
ElementType: types.StringType, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func (o *dataSourceDatacenterIbaWidgets) 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 | ||
} | ||
|
||
ws, err := bpClient.GetAllIbaWidgets(ctx) | ||
if err != nil { | ||
resp.Diagnostics.AddError("error retrieving IBA Widgets", err.Error()) | ||
return | ||
} | ||
|
||
ids := make([]apstra.ObjectId, len(ws)) | ||
for i, j := range ws { | ||
ids[i] = j.Id | ||
} | ||
|
||
idSet, diags := types.SetValueFrom(ctx, types.StringType, ids) | ||
resp.Diagnostics.Append(diags...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
// 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.