Skip to content

Commit

Permalink
initial commit that has datasources and resources to support probe cr…
Browse files Browse the repository at this point in the history
…eation
  • Loading branch information
rajagopalans committed Oct 14, 2023
1 parent f615b27 commit 75f64bc
Show file tree
Hide file tree
Showing 8 changed files with 548 additions and 1 deletion.
72 changes: 72 additions & 0 deletions apstra/data_source_iba_predefined_probe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
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 = &dataSourceIbaPredefinedProbe{}

type dataSourceIbaPredefinedProbe struct {
client *apstra.Client
}

func (o *dataSourceIbaPredefinedProbe) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_iba_predefined_probe"
}

func (o *dataSourceIbaPredefinedProbe) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
o.client = DataSourceGetClient(ctx, req, resp)
}

func (o *dataSourceIbaPredefinedProbe) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "This data source provides details of a specific IBA Predefined Probe in a Blueprint.",
Attributes: iba.IbaPredefinedProbe{}.DataSourceAttributes(),
}
}

func (o *dataSourceIbaPredefinedProbe) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var config iba.IbaPredefinedProbe
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
}
api, err := bpClient.GetIbaPredefinedProbeByName(ctx, config.Name.ValueString())
if err != nil {
if utils.IsApstra404(err) {
resp.Diagnostics.AddAttributeError(
path.Root("name"),
"IBA widget not found",
fmt.Sprintf("IBA Predefined Probe with name %s not found", config.Name))
return
}
resp.Diagnostics.AddAttributeError(
path.Root("name"), "Failed reading IBA Predefined Probe", err.Error(),
)
return
}
config.LoadApiData(ctx, api, &resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
}
// Set state
resp.Diagnostics.Append(resp.State.Set(ctx, &config)...)
}
93 changes: 93 additions & 0 deletions apstra/data_source_iba_predefined_probes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
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 = &dataSourceIbaPredefinedProbes{}

type dataSourceIbaPredefinedProbes struct {
client *apstra.Client
}

func (o *dataSourceIbaPredefinedProbes) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_iba_predefined_probes"
}

func (o *dataSourceIbaPredefinedProbes) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
o.client = DataSourceGetClient(ctx, req, resp)
}

func (o *dataSourceIbaPredefinedProbes) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: "This data source returns the IDs of the IBA Predefined Probes in a Blueprint.",
Attributes: map[string]schema.Attribute{
"blueprint_id": schema.StringAttribute{
MarkdownDescription: "Apstra Blueprint ID. " +
"Used to identify the Blueprint that the IBA Predefined Probes belongs to.",
Required: true,
Validators: []validator.String{stringvalidator.LengthAtLeast(1)},
},
"names": schema.SetAttribute{
MarkdownDescription: "A set of names representing the IBA Predefined Probes in the blueprint.",
Computed: true,
ElementType: types.StringType,
},
},
}
}

func (o *dataSourceIbaPredefinedProbes) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var config struct {
BlueprintId types.String `tfsdk:"blueprint_id"`
Names types.Set `tfsdk:"names"`
}

// 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.GetAllIbaPredefinedProbes(ctx)
if err != nil {
resp.Diagnostics.AddError("error retrieving IBA Predefined Probes", err.Error())
return
}

ids := make([]attr.Value, len(ws))
for i, j := range ws {
ids[i] = types.StringValue(j.Name)
}
nameSet := types.SetValueMust(types.StringType, ids)

// create new state object
state := struct {
BlueprintId types.String `tfsdk:"blueprint_id"`
Names types.Set `tfsdk:"names"`
}{
BlueprintId: config.BlueprintId,
Names: nameSet,
}

// set state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
49 changes: 49 additions & 0 deletions apstra/iba/predefined_probes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package iba

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/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
)

type IbaPredefinedProbe struct {
BlueprintId types.String `tfsdk:"blueprint_id"`
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
Schema types.String `tfsdk:"schema"`
}

func (o IbaPredefinedProbe) 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 Predefined Probe belongs to.",
Required: true,
Validators: []validator.String{stringvalidator.LengthAtLeast(1)},
},
"name": dataSourceSchema.StringAttribute{
MarkdownDescription: "Populate this field to look up a IBA Predefined Probe.",
Required: true,
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
},
"description": dataSourceSchema.StringAttribute{
MarkdownDescription: "Description of the IBA Predefined Probe",
Computed: true,
},
"schema": dataSourceSchema.StringAttribute{
MarkdownDescription: "Schema of the IBA Predefined Probe's parameters",
Computed: true,
},
}
}

func (o *IbaPredefinedProbe) LoadApiData(_ context.Context, in *apstra.IbaPredefinedProbe, d *diag.Diagnostics) {
o.Name = types.StringValue(in.Name)
o.Description = types.StringValue(in.Description)
o.Schema = types.StringValue(string(in.Schema))
}
140 changes: 140 additions & 0 deletions apstra/iba/probe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package iba

import (
"context"
"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/diag"
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/setplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
)

type IbaProbe struct {
BlueprintId types.String `tfsdk:"blueprint_id"`
Id types.String `tfsdk:"id"`
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
PredefinedIbaProbeId types.String `tfsdk:"predefined_probe_id"`
IbaProbeConfig types.String `tfsdk:"probe_config"`
Stages types.Set `tfsdk:"stages"`
}

func (o IbaProbe) ResourceAttributes() map[string]resourceSchema.Attribute {
return map[string]resourceSchema.Attribute{
"blueprint_id": resourceSchema.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": resourceSchema.StringAttribute{
MarkdownDescription: "IBA Probe ID.",
Computed: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()},
},
"name": resourceSchema.StringAttribute{
MarkdownDescription: "IBA Probe Name.",
Computed: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()},
},
"description": resourceSchema.StringAttribute{
MarkdownDescription: "Description of the IBA Probe",
Computed: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()},
},
"stages": resourceSchema.SetAttribute{
MarkdownDescription: "Description of the IBA Probe",
Computed: true,
PlanModifiers: []planmodifier.Set{setplanmodifier.UseStateForUnknown()},
ElementType: types.StringType,
},
"predefined_probe_id": resourceSchema.StringAttribute{
MarkdownDescription: "Id of predefined IBA Probe",
Required: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},
"probe_config": resourceSchema.StringAttribute{
MarkdownDescription: "Configuration elements for the IBA Probe",
Required: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},
}
}

// func (o IbaProbe) 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("name"),
// }...),
// },
// },
// "name": 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,
// },
// "default": dataSourceSchema.BoolAttribute{
// MarkdownDescription: "True if Default IbaProbe",
// Computed: true,
// },
// "predefined_dashboard": dataSourceSchema.StringAttribute{
// MarkdownDescription: "Id of predefined dashboard if any",
// Computed: true,
// },
// "updated_by": dataSourceSchema.StringAttribute{
// MarkdownDescription: "The user who updated the dashboard last",
// Computed: true,
// },
// "widget_grid": dataSourceSchema.ListAttribute{
// MarkdownDescription: "Grid of Widgets to be displayed in the dashboard",
// Computed: true,
// ElementType: types.ListType{
// ElemType: types.StringType,
// },
// Validators: []validator.List{
// listvalidator.SizeAtLeast(1),
// },
// },
// }
// }

func (o *IbaProbe) LoadApiData(ctx context.Context, in *apstra.IbaProbe, diag *diag.Diagnostics) {
o.Id = types.StringValue(in.Id.String())
o.Name = types.StringValue(in.Label)
o.Description = types.StringValue(in.Description)
s := make([]string, len(in.Stages))
for i, j := range in.Stages {
s[i] = j["name"].(string)
}
o.Stages = utils.SetValueOrNull(ctx, types.StringType, s, diag)
}

func (o *IbaProbe) Request(ctx context.Context, d *diag.Diagnostics) *apstra.IbaPredefinedProbeRequest {
return &apstra.IbaPredefinedProbeRequest{
Name: o.PredefinedIbaProbeId.ValueString(),
Data: []byte(o.IbaProbeConfig.ValueString()),
}
}
3 changes: 3 additions & 0 deletions apstra/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,8 @@ func (p *Provider) DataSources(_ context.Context) []func() datasource.DataSource
func() datasource.DataSource { return &dataSourceDatacenterSystemNodes{} },
func() datasource.DataSource { return &dataSourceDatacenterSvis{} },
func() datasource.DataSource { return &dataSourceDatacenterVirtualNetworks{} },
func() datasource.DataSource { return &dataSourceIbaPredefinedProbe{} },
func() datasource.DataSource { return &dataSourceIbaPredefinedProbes{} },
func() datasource.DataSource { return &dataSourceIbaWidget{} },
func() datasource.DataSource { return &dataSourceIbaWidgets{} },
func() datasource.DataSource { return &dataSourceIbaDashboard{} },
Expand Down Expand Up @@ -479,6 +481,7 @@ func (p *Provider) Resources(_ context.Context) []func() resource.Resource {
func() resource.Resource { return &resourceDatacenterVirtualNetwork{} },
func() resource.Resource { return &resourceDeviceAllocation{} },
func() resource.Resource { return &resourceIbaDashboard{} },
func() resource.Resource { return &resourceIbaProbe{} },
func() resource.Resource { return &resourceIntegerPool{} },
func() resource.Resource { return &resourceInterfaceMap{} },
func() resource.Resource { return &resourceIpv4Pool{} },
Expand Down
Loading

0 comments on commit 75f64bc

Please sign in to comment.