-
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 #706 from Juniper/feat/705-telemetry-service-regis…
…try-data-and-resource-provider add the code and test for the telemetry service registry entry providers
- Loading branch information
Showing
20 changed files
with
1,447 additions
and
5 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,122 @@ | ||
package analytics | ||
|
||
import ( | ||
"context" | ||
"strings" | ||
|
||
"github.com/Juniper/apstra-go-sdk/apstra" | ||
"github.com/Juniper/terraform-provider-apstra/apstra/utils" | ||
"github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" | ||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" | ||
dataSourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" | ||
"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/stringplanmodifier" | ||
"github.com/hashicorp/terraform-plugin-framework/schema/validator" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
) | ||
|
||
type TelemetryServiceRegistryEntry struct { | ||
ServiceName types.String `tfsdk:"service_name"` | ||
ApplicationSchema jsontypes.Normalized `tfsdk:"application_schema"` | ||
StorageSchemaPath types.String `tfsdk:"storage_schema_path"` | ||
Builtin types.Bool `tfsdk:"built_in"` | ||
Description types.String `tfsdk:"description"` | ||
Version types.String `tfsdk:"version"` | ||
} | ||
|
||
func (o TelemetryServiceRegistryEntry) DataSourceAttributes() map[string]dataSourceSchema.Attribute { | ||
return map[string]dataSourceSchema.Attribute{ | ||
"service_name": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Service Name. Used to identify the Service.", | ||
Required: true, | ||
Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, | ||
}, | ||
"application_schema": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Application Schema expressed in JSON", | ||
CustomType: jsontypes.NormalizedType{}, | ||
Computed: true, | ||
}, | ||
"storage_schema_path": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Storage Schema Path", | ||
Computed: true, | ||
}, | ||
"description": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Description", | ||
Computed: true, | ||
}, | ||
"version": dataSourceSchema.StringAttribute{ | ||
MarkdownDescription: "Version", | ||
Computed: true, | ||
}, | ||
"built_in": dataSourceSchema.BoolAttribute{ | ||
MarkdownDescription: "True If built in.", | ||
Computed: true, | ||
}, | ||
} | ||
} | ||
|
||
func (o TelemetryServiceRegistryEntry) ResourceAttributes() map[string]resourceSchema.Attribute { | ||
return map[string]resourceSchema.Attribute{ | ||
"service_name": resourceSchema.StringAttribute{ | ||
MarkdownDescription: "Service Name. Used to identify the Service.", | ||
Required: true, | ||
Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, | ||
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, | ||
}, | ||
"application_schema": resourceSchema.StringAttribute{ | ||
MarkdownDescription: "Application Schema expressed in JSON", | ||
CustomType: jsontypes.NormalizedType{}, | ||
Required: true, | ||
}, | ||
"storage_schema_path": resourceSchema.StringAttribute{ | ||
MarkdownDescription: "Storage Schema Path. Must be one of:\n - " + strings.Join(utils.AllStorageSchemaPaths(), "\n - ") + "\n", | ||
Required: true, | ||
Validators: []validator.String{ | ||
stringvalidator.LengthAtLeast(1), | ||
stringvalidator.OneOf(utils.AllStorageSchemaPaths()...), | ||
}, | ||
}, | ||
"description": resourceSchema.StringAttribute{ | ||
MarkdownDescription: "Description", | ||
Optional: true, | ||
Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, | ||
}, | ||
"version": resourceSchema.StringAttribute{ | ||
MarkdownDescription: "Version", | ||
Computed: true, | ||
}, | ||
"built_in": resourceSchema.BoolAttribute{ | ||
MarkdownDescription: "Indicates if provided by Apstra", | ||
Computed: true, | ||
}, | ||
} | ||
} | ||
|
||
func (o *TelemetryServiceRegistryEntry) LoadApiData(ctx context.Context, in *apstra.TelemetryServiceRegistryEntry, diag *diag.Diagnostics) { | ||
o.ServiceName = types.StringValue(in.ServiceName) | ||
o.Version = types.StringValue(in.Version) | ||
o.Description = utils.StringValueOrNull(ctx, in.Description, diag) | ||
o.Builtin = types.BoolValue(in.Builtin) | ||
o.ApplicationSchema = jsontypes.NewNormalizedValue(string(in.ApplicationSchema)) | ||
o.StorageSchemaPath = types.StringValue(utils.StringersToFriendlyString(in.StorageSchemaPath)) | ||
} | ||
|
||
func (o *TelemetryServiceRegistryEntry) Request(_ context.Context, diags *diag.Diagnostics) *apstra.TelemetryServiceRegistryEntry { | ||
var storageSchemaPath apstra.StorageSchemaPath | ||
err := utils.ApiStringerFromFriendlyString(&storageSchemaPath, o.StorageSchemaPath.ValueString()) | ||
if err != nil { | ||
diags.AddError("Failed to Parse Storage Schema Path", err.Error()) | ||
return nil | ||
} | ||
|
||
return &apstra.TelemetryServiceRegistryEntry{ | ||
ServiceName: o.ServiceName.ValueString(), | ||
ApplicationSchema: []byte(o.ApplicationSchema.ValueString()), | ||
StorageSchemaPath: storageSchemaPath, | ||
Builtin: o.Builtin.ValueBool(), | ||
Description: o.Description.ValueString(), | ||
Version: o.Version.ValueString(), | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package tfapstra | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/Juniper/apstra-go-sdk/apstra" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource" | ||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
) | ||
|
||
var ( | ||
_ datasource.DataSourceWithConfigure = &dataSourceTelemetryServiceRegistryEntries{} | ||
_ datasourceWithSetClient = &dataSourceTelemetryServiceRegistryEntries{} | ||
) | ||
|
||
type dataSourceTelemetryServiceRegistryEntries struct { | ||
client *apstra.Client | ||
} | ||
|
||
func (o *dataSourceTelemetryServiceRegistryEntries) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_telemetry_service_registry_entries" | ||
} | ||
|
||
func (o *dataSourceTelemetryServiceRegistryEntries) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { | ||
configureDataSource(ctx, o, req, resp) | ||
} | ||
|
||
func (o *dataSourceTelemetryServiceRegistryEntries) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
MarkdownDescription: docCategoryDesign + "This data source returns the Service Names of Telemetry Service Registry Entries.", | ||
Attributes: map[string]schema.Attribute{ | ||
"service_names": schema.SetAttribute{ | ||
MarkdownDescription: "A set of Service Names", | ||
Computed: true, | ||
ElementType: types.StringType, | ||
}, | ||
"built_in": schema.BoolAttribute{ | ||
MarkdownDescription: "Return only built_in if true, not built_in if false, all otherwise", | ||
Optional: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func (o *dataSourceTelemetryServiceRegistryEntries) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var config struct { | ||
ServiceNames types.Set `tfsdk:"service_names"` | ||
BuiltIn types.Bool `tfsdk:"built_in"` | ||
} | ||
|
||
// get the configuration | ||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
tses, err := o.client.GetAllTelemetryServiceRegistryEntries(ctx) | ||
if err != nil { | ||
resp.Diagnostics.AddError("error retrieving Telemetry Service Registry Entries", err.Error()) | ||
return | ||
} | ||
var snames []string | ||
for _, t := range tses { | ||
if config.BuiltIn.IsUnknown() || config.BuiltIn.IsNull() || config.BuiltIn.ValueBool() == t.Builtin { | ||
snames = append(snames, t.ServiceName) | ||
} | ||
} | ||
|
||
snameSet, diags := types.SetValueFrom(ctx, types.StringType, snames) | ||
resp.Diagnostics.Append(diags...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
// create new state object | ||
var state struct { | ||
ServiceNames types.Set `tfsdk:"service_names"` | ||
BuiltIn types.Bool `tfsdk:"built_in"` | ||
} | ||
state.ServiceNames = snameSet | ||
state.BuiltIn = config.BuiltIn | ||
// set state | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) | ||
} | ||
|
||
func (o *dataSourceTelemetryServiceRegistryEntries) setClient(client *apstra.Client) { | ||
o.client = client | ||
} |
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,71 @@ | ||
package tfapstra | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/Juniper/apstra-go-sdk/apstra" | ||
"github.com/Juniper/terraform-provider-apstra/apstra/analytics" | ||
"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 = &dataSourceTelemetryServiceRegistryEntry{} | ||
_ datasourceWithSetClient = &dataSourceTelemetryServiceRegistryEntry{} | ||
) | ||
|
||
type dataSourceTelemetryServiceRegistryEntry struct { | ||
client *apstra.Client | ||
} | ||
|
||
func (o *dataSourceTelemetryServiceRegistryEntry) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_telemetry_service_registry_entry" | ||
} | ||
|
||
func (o *dataSourceTelemetryServiceRegistryEntry) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { | ||
configureDataSource(ctx, o, req, resp) | ||
} | ||
|
||
func (o *dataSourceTelemetryServiceRegistryEntry) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = schema.Schema{ | ||
MarkdownDescription: docCategoryDesign + "This data source provides details of a specific Telemetry Service Registry Entry.", | ||
Attributes: analytics.TelemetryServiceRegistryEntry{}.DataSourceAttributes(), | ||
} | ||
} | ||
|
||
func (o *dataSourceTelemetryServiceRegistryEntry) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var config analytics.TelemetryServiceRegistryEntry | ||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
api, err := o.client.GetTelemetryServiceRegistryEntry(ctx, config.ServiceName.ValueString()) | ||
if utils.IsApstra404(err) { | ||
resp.Diagnostics.AddAttributeError( | ||
path.Root("name"), | ||
"TelemetryServiceRegistryEntry not found", | ||
fmt.Sprintf("TelemetryServiceRegistryEntry with Name %q not found", config.ServiceName.ValueString())) | ||
return | ||
} | ||
if err != nil { // catch errors other than 404 from above | ||
resp.Diagnostics.AddError("Error retrieving TelemetryServiceRegistryEntry", err.Error()) | ||
return | ||
} | ||
|
||
// create new state object | ||
var state analytics.TelemetryServiceRegistryEntry | ||
state.LoadApiData(ctx, api, &resp.Diagnostics) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
// Set state | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) | ||
} | ||
|
||
func (o *dataSourceTelemetryServiceRegistryEntry) setClient(client *apstra.Client) { | ||
o.client = client | ||
} |
62 changes: 62 additions & 0 deletions
62
apstra/data_source_telemetry_service_registry_entry_test.go
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,62 @@ | ||
package tfapstra | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"strings" | ||
"testing" | ||
|
||
testutils "github.com/Juniper/terraform-provider-apstra/apstra/test_utils" | ||
"github.com/Juniper/terraform-provider-apstra/apstra/utils" | ||
"github.com/hashicorp/terraform-plugin-framework/diag" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
"github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
) | ||
|
||
const ( | ||
dataSourceTelemetryServiceRegistryByServiceNameHCL = ` | ||
data "apstra_telemetry_service_registry_entry" "test" { | ||
service_name = "%s" | ||
} | ||
` | ||
) | ||
|
||
func TestAccDataSourceTelemetryServiceRegistryEntry(t *testing.T) { | ||
ctx := context.Background() | ||
|
||
ts := testutils.TelemetryServiceRegistryEntryA(t, ctx) | ||
|
||
TestAppSchema := func(state string) error { | ||
var diags diag.Diagnostics | ||
if !utils.JSONEqual(types.StringValue(state), types.StringValue(string(ts.ApplicationSchema)), &diags) { | ||
return fmt.Errorf("input schema does not match output Input %v. Output %v", ts.ApplicationSchema, state) | ||
} | ||
if diags.HasError() { | ||
var sb strings.Builder | ||
for _, d := range diags.Errors() { | ||
sb.WriteString(d.Summary() + "\n") | ||
sb.WriteString(d.Detail() + "\n") | ||
} | ||
return errors.New(sb.String()) | ||
} | ||
return nil | ||
} | ||
|
||
resource.Test(t, resource.TestCase{ | ||
// PreCheck: setup, | ||
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, | ||
Steps: []resource.TestStep{ | ||
// Read by ID | ||
{ | ||
Config: insecureProviderConfigHCL + fmt.Sprintf(dataSourceTelemetryServiceRegistryByServiceNameHCL, ts.ServiceName), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
// Verify data source/resource fields match | ||
resource.TestCheckResourceAttr("data.apstra_telemetry_service_registry_entry.test", "service_name", ts.ServiceName), | ||
resource.TestCheckResourceAttr("data.apstra_telemetry_service_registry_entry.test", "storage_schema_path", utils.StringersToFriendlyString(ts.StorageSchemaPath)), | ||
resource.TestCheckResourceAttrWith("data.apstra_telemetry_service_registry_entry.test", "application_schema", TestAppSchema), | ||
), | ||
}, | ||
}, | ||
}) | ||
} |
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.