-
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.
fixed ra_group items, examples, make docs
- Loading branch information
Showing
12 changed files
with
879 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,167 @@ | ||
package blueprint | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" | ||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" | ||
"regexp" | ||
|
||
"github.com/Juniper/apstra-go-sdk/apstra" | ||
"github.com/Juniper/terraform-provider-apstra/apstra/utils" | ||
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" | ||
"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" | ||
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/stringplanmodifier" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
) | ||
|
||
//{ | ||
// "parent_id": "string", | ||
// "label": "string", | ||
// "tags": [ | ||
// "string" | ||
// ], | ||
// "data": {} | ||
//} | ||
|
||
type FreeformRaGroup struct { | ||
BlueprintId types.String `tfsdk:"blueprint_id"` | ||
Id types.String `tfsdk:"id"` | ||
Name types.String `tfsdk:"name"` | ||
ParentId types.String `tfsdk:"parent_id"` | ||
Tags types.Set `tfsdk:"tags"` | ||
Data jsontypes.Normalized `tfsdk:"data"` | ||
GeneratorId types.String `tfsdk:"generator_id"` | ||
} | ||
|
||
func (o FreeformRaGroup) DataSourceAttributes() map[string]dataSourceSchema.Attribute { | ||
return map[string]dataSourceSchema.Attribute{ | ||
"blueprint_id": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Apstra Blueprint ID. Used to identify " + | ||
"the Blueprint where the Resource Allocation Group lives.", | ||
Required: true, | ||
Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, | ||
}, | ||
"id": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Populate this field to look up the Freeform Allocation Group 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 the Allocation Group by Name. Required when `id` is omitted.", | ||
Optional: true, | ||
Computed: true, | ||
Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, | ||
}, | ||
"parent_id": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "ID of the group node that is present as a parent of the current one in " + | ||
"parent/children relationship." + | ||
" If group is a top-level one, then 'parent_id' is equal to None/null.", | ||
Computed: true, | ||
}, | ||
"tags": dataSourceSchema.SetAttribute{ | ||
MarkdownDescription: "Set of Tag labels", | ||
ElementType: types.StringType, | ||
Computed: true, | ||
}, | ||
"data": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Arbitrary key-value mapping that is useful in a context of this group. " + | ||
"For example, you can store some VRF-related data there or add properties that are useful " + | ||
"only in context of resource allocation, but not systems or interfaces.", | ||
Computed: true, | ||
CustomType: jsontypes.NormalizedType{}, | ||
}, | ||
"generator_id": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "ID of the group generator that created the group.", | ||
Computed: true, | ||
}, | ||
} | ||
} | ||
|
||
func (o FreeformRaGroup) ResourceAttributes() map[string]resourceSchema.Attribute { | ||
return map[string]resourceSchema.Attribute{ | ||
"blueprint_id": resourceSchema.StringAttribute{ | ||
MarkdownDescription: "Apstra Blueprint ID.", | ||
Required: true, | ||
Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, | ||
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, | ||
}, | ||
"id": resourceSchema.StringAttribute{ | ||
MarkdownDescription: "ID of the Freeform Resource Allocation Group.", | ||
Computed: true, | ||
PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, | ||
}, | ||
"name": resourceSchema.StringAttribute{ | ||
MarkdownDescription: "Freeform Resource Allocation Group name as shown in the Web UI.", | ||
Required: true, | ||
Validators: []validator.String{ | ||
stringvalidator.RegexMatches(regexp.MustCompile("^[a-zA-Z0-9.-_]+$"), "name may consist only of the following characters : a-zA-Z0-9.-_")}, | ||
}, | ||
"parent_id": resourceSchema.StringAttribute{ | ||
MarkdownDescription: fmt.Sprintf("Type of the System. Must be one of `%s` or `%s`", apstra.SystemTypeInternal, apstra.SystemTypeExternal), | ||
Optional: true, | ||
Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, | ||
}, | ||
"tags": resourceSchema.SetAttribute{ | ||
MarkdownDescription: "Set of Tag labels", | ||
ElementType: types.StringType, | ||
Optional: true, | ||
Validators: []validator.Set{setvalidator.SizeAtLeast(1)}, | ||
}, | ||
"data": resourceSchema.StringAttribute{ | ||
MarkdownDescription: "Arbitrary key-value mapping that is useful in a context of this group. " + | ||
"For example, you can store some VRF-related data there or add properties that are useful" + | ||
" only in context of resource allocation, but not systems or interfaces. ", | ||
Optional: true, | ||
Computed: true, | ||
Default: stringdefault.StaticString("{}"), | ||
CustomType: jsontypes.NormalizedType{}, | ||
}, | ||
"generator_id": resourceSchema.StringAttribute{ | ||
MarkdownDescription: "ID of the Generator that created Resource Allocation Group, " + | ||
"always `null` because groups created with this resource were not generated.", | ||
Computed: true, | ||
}, | ||
} | ||
} | ||
|
||
func (o *FreeformRaGroup) Request(ctx context.Context, diags *diag.Diagnostics) *apstra.FreeformRaGroupData { | ||
var tags []string | ||
diags.Append(o.Tags.ElementsAs(ctx, &tags, false)...) | ||
if diags.HasError() { | ||
return nil | ||
} | ||
|
||
return &apstra.FreeformRaGroupData{ | ||
ParentId: (*apstra.ObjectId)(o.ParentId.ValueStringPointer()), | ||
Label: o.Name.ValueString(), | ||
Tags: tags, | ||
Data: json.RawMessage(o.Data.ValueString()), | ||
GeneratorId: (*apstra.ObjectId)(o.GeneratorId.ValueStringPointer()), | ||
} | ||
} | ||
|
||
func (o *FreeformRaGroup) LoadApiData(ctx context.Context, in *apstra.FreeformRaGroupData, diags *diag.Diagnostics) { | ||
o.Name = types.StringValue(in.Label) | ||
if in.ParentId != nil { | ||
o.ParentId = types.StringValue(string(*in.ParentId)) | ||
} | ||
|
||
o.Data = jsontypes.NewNormalizedValue(string(in.Data)) | ||
o.Tags = utils.SetValueOrNull(ctx, types.StringType, in.Tags, diags) // safe to ignore diagnostic here | ||
o.GeneratorId = types.StringPointerValue((*string)(in.GeneratorId)) | ||
} |
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,101 @@ | ||
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" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
) | ||
|
||
var ( | ||
_ datasource.DataSourceWithConfigure = &dataSourceFreeformRaGroup{} | ||
_ datasourceWithSetFfBpClientFunc = &dataSourceFreeformRaGroup{} | ||
) | ||
|
||
type dataSourceFreeformRaGroup struct { | ||
getBpClientFunc func(context.Context, string) (*apstra.FreeformClient, error) | ||
} | ||
|
||
func (o *dataSourceFreeformRaGroup) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_freeform_ra_group" | ||
} | ||
|
||
func (o *dataSourceFreeformRaGroup) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { | ||
configureDataSource(ctx, o, req, resp) | ||
} | ||
|
||
func (o *dataSourceFreeformRaGroup) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
MarkdownDescription: docCategoryFreeform + "This data source provides details of a specific Freeform Resource Allocation Group.\n\n" + | ||
"At least one optional attribute is required.", | ||
Attributes: blueprint.FreeformRaGroup{}.DataSourceAttributes(), | ||
} | ||
} | ||
|
||
func (o *dataSourceFreeformRaGroup) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var config blueprint.FreeformRaGroup | ||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
// get a client for the Freeform reference design | ||
bp, err := o.getBpClientFunc(ctx, 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.FreeformRaGroup | ||
switch { | ||
case !config.Id.IsNull(): | ||
api, err = bp.GetRaGroup(ctx, apstra.ObjectId(config.Id.ValueString())) | ||
if utils.IsApstra404(err) { | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("id"), | ||
"Freeform Resource Allocation Group not found", | ||
fmt.Sprintf("Freeform Resource Allocation Group with ID %s not found", config.Id)) | ||
return | ||
} | ||
case !config.Name.IsNull(): | ||
api, err = bp.GetRaGroupByName(ctx, config.Name.ValueString()) | ||
if utils.IsApstra404(err) { | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("name"), | ||
"Freeform Resource Allocation Group not found", | ||
fmt.Sprintf("Freeform resource allocation group with Name %s not found", config.Name)) | ||
return | ||
} | ||
} | ||
if err != nil { | ||
resp.Diagnostics.AddError("failed reading Freeform Resource Allocation Group", err.Error()) | ||
return | ||
} | ||
if api.Data == nil { | ||
resp.Diagnostics.AddError("failed reading Freeform Resource Allocation Group", "api response has no payload") | ||
return | ||
} | ||
|
||
config.Id = types.StringValue(api.Id.String()) | ||
config.LoadApiData(ctx, api.Data, &resp.Diagnostics) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
// Set state | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &config)...) | ||
} | ||
|
||
func (o *dataSourceFreeformRaGroup) setBpClientFunc(f func(context.Context, string) (*apstra.FreeformClient, error)) { | ||
o.getBpClientFunc = f | ||
} |
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
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.