Skip to content

Commit

Permalink
also add the sensor data source
Browse files Browse the repository at this point in the history
  • Loading branch information
1riatsila1 committed Oct 22, 2024
1 parent b93040a commit ebdd135
Show file tree
Hide file tree
Showing 3 changed files with 305 additions and 0 deletions.
163 changes: 163 additions & 0 deletions pkg/config-api-provider/provider/data-sources/sensor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package datasources

import (
"context"

config_api_client "github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/util"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var (
_ datasource.DataSource = &sensorDataSource{}
_ datasource.DataSourceWithConfigure = &sensorDataSource{}
)

func NewSensorDataSource() datasource.DataSource {
return &sensorDataSource{}
}

type sensorDataSource struct {
client *config_api_client.APIClient
}

type sensorDataSourceModel struct {
Id types.String `tfsdk:"id"`
Serial types.String `tfsdk:"serial"`
Name types.String `tfsdk:"name"`
ModelNumber types.String `tfsdk:"model_number"`
WifiMacAddress types.String `tfsdk:"wifi_mac_address"`
EthernetMacAddress types.String `tfsdk:"ethernet_mac_address"`
AddressNote types.String `tfsdk:"address_note"`
Longitude types.Float32 `tfsdk:"longitude"`
Latitude types.Float32 `tfsdk:"latitude"`
Notes types.String `tfsdk:"notes"`
PcapMode types.String `tfsdk:"pcap_mode"`
Filter struct {
SensorID types.String `tfsdk:"sensor_id"`
} `tfsdk:"filter"`
}

func (d *sensorDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_sensor"
}

func (d *sensorDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
},
"serial": schema.StringAttribute{
Computed: true,
},
"name": schema.StringAttribute{
Computed: true,
},
"model_number": schema.StringAttribute{
Computed: true,
},
"wifi_mac_address": schema.StringAttribute{
Computed: true,
},
"ethernet_mac_address": schema.StringAttribute{
Computed: true,
},
"address_note": schema.StringAttribute{
Computed: true,
},
"longitude": schema.Float32Attribute{
Computed: true,
},
"latitude": schema.Float32Attribute{
Computed: true,
},
"notes": schema.StringAttribute{
Computed: true,
},
"pcap_mode": schema.StringAttribute{
Computed: true,
},
"filter": schema.SingleNestedAttribute{
Required: true,
Attributes: map[string]schema.Attribute{
"sensor_id": schema.StringAttribute{
Required: true,
},
},
},
},
}
}

func (d *sensorDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var state sensorDataSourceModel

// Read configuration from request
diags := req.Config.Get(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

Check warning on line 103 in pkg/config-api-provider/provider/data-sources/sensor.go

View check run for this annotation

Codecov / codecov/patch

pkg/config-api-provider/provider/data-sources/sensor.go#L102-L103

Added lines #L102 - L103 were not covered by tests

request := d.client.ConfigurationAPI.
GetUxiV1alpha1SensorsGet(ctx).
Id(state.Filter.SensorID.ValueString())

sensorResponse, response, err := util.RetryFor429(request.Execute)
errorPresent, errorDetail := util.RaiseForStatus(response, err)

errorSummary := util.GenerateErrorSummary("read", "uxi_sensor")

if errorPresent {
resp.Diagnostics.AddError(errorSummary, errorDetail)
return
}

if len(sensorResponse.Items) != 1 {
resp.Diagnostics.AddError(errorSummary, "Could not find specified data source")
return
}

sensor := sensorResponse.Items[0]

state.Id = types.StringValue(sensor.Id)
state.Name = types.StringValue(sensor.Name)
state.ModelNumber = types.StringPointerValue(sensor.ModelNumber.Get())
state.WifiMacAddress = types.StringPointerValue(sensor.WifiMacAddress.Get())
state.EthernetMacAddress = types.StringPointerValue(sensor.EthernetMacAddress.Get())
state.AddressNote = types.StringPointerValue(sensor.AddressNote.Get())
state.Longitude = types.Float32PointerValue(sensor.Longitude.Get())
state.Latitude = types.Float32PointerValue(sensor.Latitude.Get())
state.Notes = types.StringPointerValue(sensor.Notes.Get())
state.PcapMode = types.StringPointerValue(sensor.PcapMode.Get())

// Set state
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

Check warning on line 142 in pkg/config-api-provider/provider/data-sources/sensor.go

View check run for this annotation

Codecov / codecov/patch

pkg/config-api-provider/provider/data-sources/sensor.go#L141-L142

Added lines #L141 - L142 were not covered by tests
}

func (d *sensorDataSource) 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. Please report this issue to the provider developers.",
)
return
}

Check warning on line 160 in pkg/config-api-provider/provider/data-sources/sensor.go

View check run for this annotation

Codecov / codecov/patch

pkg/config-api-provider/provider/data-sources/sensor.go#L155-L160

Added lines #L155 - L160 were not covered by tests

d.client = client
}
1 change: 1 addition & 0 deletions pkg/config-api-provider/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ func (p *uxiConfigurationProvider) Configure(ctx context.Context, req provider.C
func (p *uxiConfigurationProvider) DataSources(_ context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
datasources.NewGroupDataSource,
datasources.NewSensorDataSource,
datasources.NewWiredNetworkDataSource,
datasources.NewWirelessNetworkDataSource,
datasources.NewSensorGroupAssignmentDataSource,
Expand Down
141 changes: 141 additions & 0 deletions pkg/config-api-provider/test/data-sources/sensor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package data_source_test

import (
"regexp"
"testing"

"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/test/provider"
"github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/test/util"
"github.com/h2non/gock"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/nbio/st"
)

func TestSensorDataSource(t *testing.T) {
defer gock.Off()
mockOAuth := util.MockOAuth()

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: provider.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Test Read
{
PreConfig: func() {
util.MockGetSensor(
"uid",
util.GeneratePaginatedResponse([]map[string]interface{}{util.GenerateSensorResponseModel("uid", "")}),
3,
)
},
Config: provider.ProviderConfig + `
data "uxi_sensor" "my_sensor" {
filter = {
sensor_id = "uid"
}
}
`,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.uxi_sensor.my_sensor", "id", "uid"),
),
},
},
})

mockOAuth.Mock.Disable()
}

func TestSensorDataSource429Handling(t *testing.T) {
defer gock.Off()
mockOAuth := util.MockOAuth()
var mock429 *gock.Response

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: provider.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{

// Test Read
{
PreConfig: func() {
mock429 = gock.New("https://test.api.capenetworks.com").
Get("/uxi/v1alpha1/sensors").
Reply(429).
SetHeaders(util.RateLimitingHeaders)
util.MockGetSensor(
"uid",
util.GeneratePaginatedResponse([]map[string]interface{}{util.GenerateSensorResponseModel("uid", "")}),
3,
)
},
Config: provider.ProviderConfig + `
data "uxi_sensor" "my_sensor" {
filter = {
sensor_id = "uid"
}
}
`,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.uxi_sensor.my_sensor", "id", "uid"),
func(s *terraform.State) error {
st.Assert(t, mock429.Mock.Request().Counter, 0)
return nil
},
),
},
},
})

mockOAuth.Mock.Disable()
}

func TestSensorDataSourceHttpErrorHandling(t *testing.T) {
defer gock.Off()
mockOAuth := util.MockOAuth()
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: provider.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// 5xx error
{
PreConfig: func() {
gock.New("https://test.api.capenetworks.com").
Get("/uxi/v1alpha1/sensors").
Reply(500).
JSON(map[string]interface{}{
"httpStatusCode": 500,
"errorCode": "HPE_GL_ERROR_INTERNAL_SERVER_ERROR",
"message": "Current request cannot be processed due to unknown issue",
"debugId": "12312-123123-123123-1231212",
})
},
Config: provider.ProviderConfig + `
data "uxi_sensor" "my_sensor" {
filter = {
sensor_id = "uid"
}
}
`,
ExpectError: regexp.MustCompile(`(?s)Current request cannot be processed due to unknown issue\s*DebugID: 12312-123123-123123-1231212`),
},
// Not found error
{
PreConfig: func() {
util.MockGetSensor(
"uid",
util.GeneratePaginatedResponse([]map[string]interface{}{}),
1,
)
},
Config: provider.ProviderConfig + `
data "uxi_sensor" "my_sensor" {
filter = {
sensor_id = "uid"
}
}
`,
ExpectError: regexp.MustCompile(`Could not find specified data source`),
},
},
})

mockOAuth.Mock.Disable()
}

0 comments on commit ebdd135

Please sign in to comment.