diff --git a/internal/provider/resources/service.go b/internal/provider/resources/service.go index c2224c8f..9942d32a 100644 --- a/internal/provider/resources/service.go +++ b/internal/provider/resources/service.go @@ -2,8 +2,9 @@ package resources import ( "context" + "github.com/aruba-uxi/terraform-provider-configuration/internal/provider/util" - // "github.com/aruba-uxi/terraform-provider-configuration-api/pkg/config-api-client" + "github.com/aruba-uxi/terraform-provider-configuration-api/pkg/config-api-client" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" @@ -23,21 +24,13 @@ type serviceTestResourceModel struct { Name types.String `tfsdk:"name"` } -// TODO: Switch this to use the Client Model when that becomes available -type ServiceTestResponseModel struct { - Uid string // , - Category string // , - Name string // , - Target string // Nullable<>, - Template string // , - IsEnabled bool // -} - func NewServiceTestResource() resource.Resource { return &serviceTestResource{} } -type serviceTestResource struct{} +type serviceTestResource struct { + client *config_api_client.APIClient +} func (r *serviceTestResource) Metadata( ctx context.Context, @@ -72,6 +65,23 @@ func (r *serviceTestResource) Configure( req resource.ConfigureRequest, resp *resource.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", + "Resource type: Group. Please report this issue to the provider developers.", + ) + return + } + + r.client = client } func (r *serviceTestResource) Create( @@ -102,10 +112,27 @@ func (r *serviceTestResource) Read( return } - response := GetServiceTest(state.ID.ValueString()) + request := r.client.ConfigurationAPI. + ServiceTestsGet(ctx). + Id(state.ID.ValueString()) + sensorResponse, response, err := util.RetryFor429(request.Execute) + errorPresent, errorDetail := util.RaiseForStatus(response, err) + + errorSummary := util.GenerateErrorSummary("read", "uxi_service_test") + + if errorPresent { + resp.Diagnostics.AddError(errorSummary, errorDetail) + return + } + + if len(sensorResponse.Items) != 1 { + resp.State.RemoveResource(ctx) + return + } + serviceTest := sensorResponse.Items[0] // Update state from client response - state.Name = types.StringValue(response.Name) + state.Name = types.StringValue(serviceTest.Name) // Set refreshed state diags = resp.State.Set(ctx, &state) @@ -152,17 +179,3 @@ func (r *serviceTestResource) ImportState( ) { resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) } - -// Get the serviceTest using the configuration-api client -var GetServiceTest = func(uid string) ServiceTestResponseModel { - // TODO: Query the serviceTest using the client - - return ServiceTestResponseModel{ - Uid: uid, - Category: "category", - Name: "name", - Target: "target", - Template: "template", - IsEnabled: true, - } -} diff --git a/test/mocked/resources/service_test.go b/test/mocked/resources/service_test.go index 9c8cdc75..bc71b385 100644 --- a/test/mocked/resources/service_test.go +++ b/test/mocked/resources/service_test.go @@ -6,7 +6,6 @@ import ( "regexp" "testing" - "github.com/aruba-uxi/terraform-provider-configuration/internal/provider/resources" "github.com/h2non/gock" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/tfversion" @@ -37,9 +36,15 @@ func TestServiceTestResource(t *testing.T) { // Importing a service_test { PreConfig: func() { - resources.GetServiceTest = func(uid string) resources.ServiceTestResponseModel { - return util.GenerateServiceTestResponseModel(uid, "") - } + util.MockGetServiceTest( + "uid", + util.GeneratePaginatedResponse( + []map[string]interface{}{ + util.GenerateServiceTestResponseModel("uid", ""), + }, + ), + 2, + ) }, Config: provider.ProviderConfig + ` resource "uxi_service_test" "my_service_test" { @@ -62,12 +67,34 @@ func TestServiceTestResource(t *testing.T) { }, // ImportState testing { + PreConfig: func() { + util.MockGetServiceTest( + "uid", + util.GeneratePaginatedResponse( + []map[string]interface{}{ + util.GenerateServiceTestResponseModel("uid", ""), + }, + ), + 1, + ) + }, ResourceName: "uxi_service_test.my_service_test", ImportState: true, ImportStateVerify: true, }, // Updating a service_test is not allowed { + PreConfig: func() { + util.MockGetServiceTest( + "uid", + util.GeneratePaginatedResponse( + []map[string]interface{}{ + util.GenerateServiceTestResponseModel("uid", ""), + }, + ), + 1, + ) + }, Config: provider.ProviderConfig + ` resource "uxi_service_test" "my_service_test" { name = "updated_name" @@ -78,6 +105,17 @@ func TestServiceTestResource(t *testing.T) { }, // Deleting a service_test is not allowed { + PreConfig: func() { + util.MockGetServiceTest( + "uid", + util.GeneratePaginatedResponse( + []map[string]interface{}{ + util.GenerateServiceTestResponseModel("uid", ""), + }, + ), + 1, + ) + }, Config: provider.ProviderConfig + ``, ExpectError: regexp.MustCompile( `(?s)deleting a service_test is not supported; service_tests can only removed from\s*state`, diff --git a/test/mocked/resources/service_test_group_assignment_test.go b/test/mocked/resources/service_test_group_assignment_test.go index 0e8991ab..9db90da5 100644 --- a/test/mocked/resources/service_test_group_assignment_test.go +++ b/test/mocked/resources/service_test_group_assignment_test.go @@ -26,10 +26,15 @@ func TestServiceTestGroupAssignmentResource(t *testing.T) { { PreConfig: func() { // required for serviceTest import - resources.GetServiceTest = func(uid string) resources.ServiceTestResponseModel { - return util.GenerateServiceTestResponseModel(uid, "") - } - + util.MockGetServiceTest( + "service_test_uid", + util.GeneratePaginatedResponse( + []map[string]interface{}{ + util.GenerateServiceTestResponseModel("service_test_uid", ""), + }, + ), + 2, + ) // required for group create util.MockPostGroup( util.GenerateGroupRequestModel("group_uid", "", ""), @@ -47,7 +52,6 @@ func TestServiceTestGroupAssignmentResource(t *testing.T) { ), 1, ) - // required for serviceTest group assignment create util.MockPostServiceTestGroupAssignment( util.GenerateServiceTestGroupAssignmentRequest( @@ -116,13 +120,24 @@ func TestServiceTestGroupAssignmentResource(t *testing.T) { // Update and Read testing { PreConfig: func() { - resources.GetServiceTest = func(uid string) resources.ServiceTestResponseModel { - if uid == "service_test_uid" { - return util.GenerateServiceTestResponseModel("service_test_uid", "") - } else { - return util.GenerateServiceTestResponseModel("service_test_uid", "_2") - } - } + util.MockGetServiceTest( + "service_test_uid_2", + util.GeneratePaginatedResponse( + []map[string]interface{}{ + util.GenerateServiceTestResponseModel("service_test_uid_2", "_2"), + }, + ), + 2, + ) + util.MockGetServiceTest( + "service_test_uid", + util.GeneratePaginatedResponse( + []map[string]interface{}{ + util.GenerateServiceTestResponseModel("service_test_uid", ""), + }, + ), + 2, + ) util.MockGetGroup( "group_uid_2", util.GeneratePaginatedResponse( @@ -297,9 +312,15 @@ func TestServiceTestGroupAssignmentResource429Handling(t *testing.T) { { PreConfig: func() { // required for serviceTest import - resources.GetServiceTest = func(uid string) resources.ServiceTestResponseModel { - return util.GenerateServiceTestResponseModel(uid, "") - } + util.MockGetServiceTest( + "service_test_uid", + util.GeneratePaginatedResponse( + []map[string]interface{}{ + util.GenerateServiceTestResponseModel("service_test_uid", ""), + }, + ), + 2, + ) // required for group create util.MockPostGroup( @@ -419,9 +440,15 @@ func TestServiceTestGroupAssignmentResourceHttpErrorHandling(t *testing.T) { { PreConfig: func() { // required for serviceTest import - resources.GetServiceTest = func(uid string) resources.ServiceTestResponseModel { - return util.GenerateServiceTestResponseModel(uid, "") - } + util.MockGetServiceTest( + "service_test_uid", + util.GeneratePaginatedResponse( + []map[string]interface{}{ + util.GenerateServiceTestResponseModel("service_test_uid", ""), + }, + ), + 1, + ) // required for group create util.MockPostGroup( diff --git a/test/mocked/util/utils.go b/test/mocked/util/utils.go index efd7a77b..f4f5863d 100644 --- a/test/mocked/util/utils.go +++ b/test/mocked/util/utils.go @@ -90,14 +90,15 @@ func GeneratePaginatedResponse(items []map[string]interface{}) map[string]interf func GenerateServiceTestResponseModel( uid string, postfix string, -) resources.ServiceTestResponseModel { - return resources.ServiceTestResponseModel{ - Uid: uid, - Category: "external" + postfix, - Name: "name" + postfix, - Target: "target" + postfix, - Template: "template" + postfix, - IsEnabled: true, +) map[string]interface{} { + return map[string]interface{}{ + "id": uid, + "category": "external" + postfix, + "name": "name" + postfix, + "target": "target" + postfix, + "template": "template" + postfix, + "isEnabled": true, + "type": "networking-uxi/service-test", } } @@ -317,6 +318,16 @@ func MockGetWirelessNetwork(uid string, response map[string]interface{}, times i JSON(response) } +func MockGetServiceTest(uid string, response map[string]interface{}, times int) { + gock.New("https://test.api.capenetworks.com"). + Get("/networking-uxi/v1alpha1/service-tests"). + MatchHeader("Authorization", "mock_token"). + MatchParam("id", uid). + Times(times). + Reply(200). + JSON(response) +} + func MockGetSensorGroupAssignment(uid string, response map[string]interface{}, times int) { gock.New("https://test.api.capenetworks.com"). Get("/networking-uxi/v1alpha1/sensor-group-assignments").