diff --git a/pkg/config-api-provider/provider/data-sources/sensor_group_assignment.go b/pkg/config-api-provider/provider/data-sources/sensor_group_assignment.go new file mode 100644 index 00000000..c90b8380 --- /dev/null +++ b/pkg/config-api-provider/provider/data-sources/sensor_group_assignment.go @@ -0,0 +1,117 @@ +package datasources + +import ( + "context" + + config_api_client "github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ datasource.DataSource = &sensorGroupAssignmentDataSource{} + _ datasource.DataSourceWithConfigure = &sensorGroupAssignmentDataSource{} +) + +func NewSensorGroupAssignmentDataSource() datasource.DataSource { + return &sensorGroupAssignmentDataSource{} +} + +type sensorGroupAssignmentDataSource struct { + client *config_api_client.APIClient +} + +type sensorGroupAssignmentDataSourceModel struct { + ID types.String `tfsdk:"id"` + SensorID types.String `tfsdk:"sensor_id"` + GroupID types.String `tfsdk:"group_id"` + Filter struct { + SensorGroupAssignmentID string `tfsdk:"sensor_group_assignment_id"` + } `tfsdk:"filter"` +} + +func (d *sensorGroupAssignmentDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_sensor_group_assignment" +} + +func (d *sensorGroupAssignmentDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "sensor_id": schema.StringAttribute{ + Computed: true, + }, + "group_id": schema.StringAttribute{ + Computed: true, + }, + "filter": schema.SingleNestedAttribute{ + Required: true, + Attributes: map[string]schema.Attribute{ + "sensor_group_assignment_id": schema.StringAttribute{ + Required: true, + }, + }, + }, + }, + } +} + +func (d *sensorGroupAssignmentDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var state sensorGroupAssignmentDataSourceModel + + // Read configuration from request + diags := req.Config.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + sensorGroupAssignmentResponse, _, err := d.client.ConfigurationAPI. + GetConfigurationAppV1SensorGroupAssignmentsGet(context.Background()). + Uid(state.Filter.SensorGroupAssignmentID). + Execute() + + if err != nil || len(sensorGroupAssignmentResponse.SensorGroupAssignments) != 1 { + resp.Diagnostics.AddError( + "Error reading Sensor Group Assignment", + "Could not retrieve Sensor Group Assignment, unexpected error: "+err.Error(), + ) + return + } + + sensorGroupAssignment := sensorGroupAssignmentResponse.SensorGroupAssignments[0] + state.ID = types.StringValue(sensorGroupAssignment.Uid) + state.SensorID = types.StringValue(sensorGroupAssignment.SensorUid) + state.GroupID = types.StringValue(sensorGroupAssignment.GroupUid) + + // Set state + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +func (d *sensorGroupAssignmentDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + // Add a nil check when handling ProviderData because Terraform + // sets that data after it calls the ConfigureProvider RPC. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*config_api_client.APIClient) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + "Data Source type: Sensor Group Assignment. Please report this issue to the provider developers.", + ) + return + } + + d.client = client +} diff --git a/pkg/config-api-provider/provider/provider.go b/pkg/config-api-provider/provider/provider.go index 55fe0eaa..82d1268a 100644 --- a/pkg/config-api-provider/provider/provider.go +++ b/pkg/config-api-provider/provider/provider.go @@ -158,6 +158,7 @@ func (p *uxiConfigurationProvider) DataSources(_ context.Context) []func() datas datasources.NewRootGroupDataSource, datasources.NewWiredNetworkDataSource, datasources.NewWirelessNetworkDataSource, + datasources.NewSensorGroupAssignmentDataSource, } } diff --git a/pkg/config-api-provider/test/data_source_sensor_group_assignment_test.go b/pkg/config-api-provider/test/data_source_sensor_group_assignment_test.go new file mode 100644 index 00000000..a05515f0 --- /dev/null +++ b/pkg/config-api-provider/test/data_source_sensor_group_assignment_test.go @@ -0,0 +1,43 @@ +package test + +import ( + "testing" + + "github.com/h2non/gock" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestSensorGroupAssignmentDataSource(t *testing.T) { + defer gock.Off() + MockOAuth() + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Read testing + { + PreConfig: func() { + MockGetSensorGroupAssignment( + "uid", + GenerateSensorGroupAssignmentPaginatedResponse([]map[string]interface{}{ + StructToMap(GenerateSensorGroupAssignmentResponse("uid", "")), + }), + 3, + ) + }, + Config: providerConfig + ` + data "uxi_sensor_group_assignment" "my_sensor_group_assignment" { + filter = { + sensor_group_assignment_id = "uid" + } + } + `, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.uxi_sensor_group_assignment.my_sensor_group_assignment", "id", "uid"), + resource.TestCheckResourceAttr("data.uxi_sensor_group_assignment.my_sensor_group_assignment", "group_id", "group_uid"), + resource.TestCheckResourceAttr("data.uxi_sensor_group_assignment.my_sensor_group_assignment", "sensor_id", "sensor_uid"), + ), + }, + }, + }) +} diff --git a/pkg/config-api-provider/test/sensor_group_assignment_test.go b/pkg/config-api-provider/test/sensor_group_assignment_test.go index eaf7c644..81067f34 100644 --- a/pkg/config-api-provider/test/sensor_group_assignment_test.go +++ b/pkg/config-api-provider/test/sensor_group_assignment_test.go @@ -36,7 +36,7 @@ func TestSensorGroupAssignmentResource(t *testing.T) { resources.CreateSensorGroupAssignment = func(request resources.SensorGroupAssignmentRequestModel) resources.SensorGroupAssignmentResponseModel { return GenerateSensorGroupAssignmentResponse("sensor_group_assignment_uid", "") } - MockGetSensorGroupAssociation( + MockGetSensorGroupAssignment( "sensor_group_assignment_uid", GenerateSensorGroupAssignmentPaginatedResponse([]map[string]interface{}{ StructToMap(GenerateSensorGroupAssignmentResponse("sensor_group_assignment_uid", "")), @@ -76,7 +76,7 @@ func TestSensorGroupAssignmentResource(t *testing.T) { // ImportState testing { PreConfig: func() { - MockGetSensorGroupAssociation( + MockGetSensorGroupAssignment( "sensor_group_assignment_uid", GenerateSensorGroupAssignmentPaginatedResponse([]map[string]interface{}{ StructToMap(GenerateSensorGroupAssignmentResponse("sensor_group_assignment_uid", "")), @@ -115,14 +115,14 @@ func TestSensorGroupAssignmentResource(t *testing.T) { MockPostGroup(StructToMap(GenerateGroupResponseModel("group_uid_2", "_2", "_2")), 1) // required for sensor group assignment create - MockGetSensorGroupAssociation( + MockGetSensorGroupAssignment( "sensor_group_assignment_uid", GenerateSensorGroupAssignmentPaginatedResponse([]map[string]interface{}{ StructToMap(GenerateSensorGroupAssignmentResponse("sensor_group_assignment_uid", "")), }), 1, ) - MockGetSensorGroupAssociation( + MockGetSensorGroupAssignment( "sensor_group_assignment_uid_2", GenerateSensorGroupAssignmentPaginatedResponse([]map[string]interface{}{ StructToMap(GenerateSensorGroupAssignmentResponse("sensor_group_assignment_uid_2", "_2")), @@ -197,14 +197,14 @@ func TestSensorGroupAssignmentResource(t *testing.T) { }), 1, ) - MockGetSensorGroupAssociation( + MockGetSensorGroupAssignment( "sensor_group_assignment_uid", GenerateSensorGroupAssignmentPaginatedResponse([]map[string]interface{}{ StructToMap(GenerateSensorGroupAssignmentResponse("sensor_group_assignment_uid", "")), }), 1, ) - MockGetSensorGroupAssociation( + MockGetSensorGroupAssignment( "sensor_group_assignment_uid_2", GenerateSensorGroupAssignmentPaginatedResponse([]map[string]interface{}{ StructToMap(GenerateSensorGroupAssignmentResponse("sensor_group_assignment_uid_2", "_2")), diff --git a/pkg/config-api-provider/test/utils.go b/pkg/config-api-provider/test/utils.go index fe1b5e8b..7d807447 100644 --- a/pkg/config-api-provider/test/utils.go +++ b/pkg/config-api-provider/test/utils.go @@ -232,7 +232,7 @@ func MockGetWirelessNetwork(uid string, response map[string]interface{}, times i JSON(response) } -func MockGetSensorGroupAssociation(uid string, response map[string]interface{}, times int) { +func MockGetSensorGroupAssignment(uid string, response map[string]interface{}, times int) { gock.New("https://test.api.capenetworks.com"). Get("/configuration/app/v1/sensor-group-assignments"). MatchHeader("Authorization", "mock_token").