diff --git a/pkg/config-api-provider/provider/resources/service_group_assignment.go b/pkg/config-api-provider/provider/resources/service_group_assignment.go index 61fb05e1..e2b91694 100644 --- a/pkg/config-api-provider/provider/resources/service_group_assignment.go +++ b/pkg/config-api-provider/provider/resources/service_group_assignment.go @@ -2,6 +2,8 @@ package resources import ( "context" + "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/path" "github.com/hashicorp/terraform-plugin-framework/resource" @@ -23,22 +25,13 @@ type serviceTestGroupAssignmentResourceModel struct { GroupID types.String `tfsdk:"group_id"` } -type ServiceTestGroupAssignmentResponseModel struct { - UID string // - GroupUID string // , - ServiceTestUID string // -} - -type ServiceTestGroupAssignmentRequestModel struct { - GroupUID string // , - ServiceTestUID string // -} - func NewServiceTestGroupAssignmentResource() resource.Resource { return &serviceTestGroupAssignmentResource{} } -type serviceTestGroupAssignmentResource struct{} +type serviceTestGroupAssignmentResource struct { + client *config_api_client.APIClient +} func (r *serviceTestGroupAssignmentResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { resp.TypeName = req.ProviderTypeName + "_service_test_group_assignment" @@ -70,6 +63,21 @@ func (r *serviceTestGroupAssignmentResource) Schema(_ context.Context, _ resourc } func (r *serviceTestGroupAssignmentResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + 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: Service Test Group Assignment. Please report this issue to the provider developers.", + ) + return + } + + r.client = client } func (r *serviceTestGroupAssignmentResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { @@ -81,16 +89,27 @@ func (r *serviceTestGroupAssignmentResource) Create(ctx context.Context, req res return } - // TODO: Call client createServiceTestGroupAssignment method - serviceTestGroupAssignment := CreateServiceTestGroupAssignment(ServiceTestGroupAssignmentRequestModel{ - GroupUID: plan.GroupID.ValueString(), - ServiceTestUID: plan.ServiceTestID.ValueString(), - }) + postRequest := config_api_client.NewServiceTestGroupAssignmentsPostRequest( + plan.GroupID.ValueString(), + plan.ServiceTestID.ValueString(), + ) + request := r.client.ConfigurationAPI. + PostUxiV1alpha1ServiceTestGroupAssignmentsPost(ctx). + ServiceTestGroupAssignmentsPostRequest(*postRequest) + serviceTestGroupAssignment, _, err := util.RetryFor429(request.Execute) + + if err != nil { + resp.Diagnostics.AddError( + "Error creating Service Test Group Assignment", + "Could not create Network Group Assignment, unexpected error: "+err.Error(), + ) + return + } // Update the state to match the plan - plan.ID = types.StringValue(serviceTestGroupAssignment.UID) - plan.GroupID = types.StringValue(serviceTestGroupAssignment.GroupUID) - plan.ServiceTestID = types.StringValue(serviceTestGroupAssignment.ServiceTestUID) + plan.ID = types.StringValue(serviceTestGroupAssignment.Id) + plan.GroupID = types.StringValue(serviceTestGroupAssignment.Group.Id) + plan.ServiceTestID = types.StringValue(serviceTestGroupAssignment.ServiceTest.Id) // Set state to fully populated data diags = resp.State.Set(ctx, plan) @@ -113,8 +132,8 @@ func (r *serviceTestGroupAssignmentResource) Read(ctx context.Context, req resou serviceTestGroupAssignment := GetServiceTestGroupAssignment(state.ID.ValueString()) // Update state from client response - state.GroupID = types.StringValue(serviceTestGroupAssignment.GroupUID) - state.ServiceTestID = types.StringValue(serviceTestGroupAssignment.ServiceTestUID) + state.GroupID = types.StringValue(serviceTestGroupAssignment.Group.Id) + state.ServiceTestID = types.StringValue(serviceTestGroupAssignment.ServiceTest.Id) // Set refreshed state diags = resp.State.Set(ctx, &state) @@ -151,22 +170,13 @@ func (r *serviceTestGroupAssignmentResource) ImportState(ctx context.Context, re resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) } -var GetServiceTestGroupAssignment = func(uid string) ServiceTestGroupAssignmentResponseModel { - // TODO: Query the serviceTestGroupAssignment using the client - - return ServiceTestGroupAssignmentResponseModel{ - UID: uid, - GroupUID: "mock_group_uid", - ServiceTestUID: "mock_serviceTest_uid", - } -} - -var CreateServiceTestGroupAssignment = func(request ServiceTestGroupAssignmentRequestModel) ServiceTestGroupAssignmentResponseModel { +var GetServiceTestGroupAssignment = func(uid string) config_api_client.ServiceTestGroupAssignmentsPostResponse { // TODO: Query the serviceTestGroupAssignment using the client - - return ServiceTestGroupAssignmentResponseModel{ - UID: "mock_uid", - GroupUID: "mock_group_uid", - ServiceTestUID: "mock_serviceTest_uid", + resourceType := "uxi/service-test-group-assignment" + return config_api_client.ServiceTestGroupAssignmentsPostResponse{ + Id: uid, + Group: *config_api_client.NewGroup("mock_group_uid"), + ServiceTest: *config_api_client.NewServiceTest("mock_serviceTest_uid"), + Type: &resourceType, } } diff --git a/pkg/config-api-provider/test/resources/service_test_group_assignment_test.go b/pkg/config-api-provider/test/resources/service_test_group_assignment_test.go index 311f6c60..049f4e9f 100644 --- a/pkg/config-api-provider/test/resources/service_test_group_assignment_test.go +++ b/pkg/config-api-provider/test/resources/service_test_group_assignment_test.go @@ -1,13 +1,17 @@ package resource_test import ( + "testing" + + 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/test/provider" "github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/test/util" - "testing" "github.com/aruba-uxi/configuration-api-terraform-provider/pkg/terraform-provider-configuration/provider/resources" "github.com/h2non/gock" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/nbio/st" ) func TestServiceTestGroupAssignmentResource(t *testing.T) { @@ -34,12 +38,13 @@ func TestServiceTestGroupAssignmentResource(t *testing.T) { ) // required for serviceTest group assignment create - serviceTestGroupAssignmentResponse := util.GenerateServiceTestGroupAssignmentResponse("service_test_group_assignment_uid", "") - resources.CreateServiceTestGroupAssignment = func(request resources.ServiceTestGroupAssignmentRequestModel) resources.ServiceTestGroupAssignmentResponseModel { - return serviceTestGroupAssignmentResponse - } - resources.GetServiceTestGroupAssignment = func(uid string) resources.ServiceTestGroupAssignmentResponseModel { - return serviceTestGroupAssignmentResponse + util.MockPostServiceTestGroupAssignment( + "service_test_group_assignment_uid", + util.StructToMap(util.GenerateServiceTestGroupAssignmentResponse("service_test_group_assignment_uid", "")), + 1, + ) + resources.GetServiceTestGroupAssignment = func(uid string) config_api_client.ServiceTestGroupAssignmentsPostResponse { + return util.GenerateServiceTestGroupAssignmentResponse("service_test_group_assignment_uid", "") } }, @@ -99,16 +104,18 @@ func TestServiceTestGroupAssignmentResource(t *testing.T) { util.MockPostGroup(util.StructToMap(util.GenerateGroupResponsePostModel("group_uid_2", "_2", "_2")), 1) // required for serviceTest group assignment create - resources.GetServiceTestGroupAssignment = func(uid string) resources.ServiceTestGroupAssignmentResponseModel { + resources.GetServiceTestGroupAssignment = func(uid string) config_api_client.ServiceTestGroupAssignmentsPostResponse { if uid == "service_test_group_assignment_uid" { return util.GenerateServiceTestGroupAssignmentResponse("service_test_group_assignment_uid", "") } else { return util.GenerateServiceTestGroupAssignmentResponse("service_test_group_assignment_uid_2", "_2") } } - resources.CreateServiceTestGroupAssignment = func(request resources.ServiceTestGroupAssignmentRequestModel) resources.ServiceTestGroupAssignmentResponseModel { - return util.GenerateServiceTestGroupAssignmentResponse("service_test_group_assignment_uid_2", "_2") - } + util.MockPostServiceTestGroupAssignment( + "service_test_group_assignment_uid_2", + util.StructToMap(util.GenerateServiceTestGroupAssignmentResponse("service_test_group_assignment_uid_2", "_2")), + 1, + ) }, Config: provider.ProviderConfig + ` // the original resources @@ -189,3 +196,95 @@ func TestServiceTestGroupAssignmentResource(t *testing.T) { mockOAuth.Mock.Disable() } + +func TestServiceTestGroupAssignmentResource429Handling(t *testing.T) { + defer gock.Off() + mockOAuth := util.MockOAuth() + var mock429 *gock.Response + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: provider.TestAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Creating a serviceTest group assignment + { + PreConfig: func() { + // required for serviceTest import + resources.GetServiceTest = func(uid string) resources.ServiceTestResponseModel { + return util.GenerateServiceTestResponseModel(uid, "") + } + + // required for group create + util.MockPostGroup(util.StructToMap(util.GenerateGroupResponsePostModel("group_uid", "", "")), 1) + util.MockGetGroup( + "group_uid", + util.GeneratePaginatedResponse([]map[string]interface{}{util.StructToMap(util.GenerateGroupResponseGetModel("group_uid", "", ""))}), + 1, + ) + + // required for serviceTest group assignment create + mock429 = gock.New("https://test.api.capenetworks.com"). + Post("/uxi/v1alpha1/service-test-group-assignments"). + Reply(429). + SetHeaders(util.RateLimitingHeaders) + + util.MockPostServiceTestGroupAssignment( + "service_test_group_assignment_uid", + util.StructToMap(util.GenerateServiceTestGroupAssignmentResponse("service_test_group_assignment_uid", "")), + 1, + ) + resources.GetServiceTestGroupAssignment = func(uid string) config_api_client.ServiceTestGroupAssignmentsPostResponse { + return util.GenerateServiceTestGroupAssignmentResponse("service_test_group_assignment_uid", "") + } + }, + + Config: provider.ProviderConfig + ` + resource "uxi_group" "my_group" { + name = "name" + parent_group_id = "parent_uid" + } + + resource "uxi_service_test" "my_service_test" { + title = "title" + } + + import { + to = uxi_service_test.my_service_test + id = "service_test_uid" + } + + resource "uxi_service_test_group_assignment" "my_service_test_group_assignment" { + service_test_id = uxi_service_test.my_service_test.id + group_id = uxi_group.my_group.id + }`, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("uxi_service_test_group_assignment.my_service_test_group_assignment", "id", "service_test_group_assignment_uid"), + func(s *terraform.State) error { + st.Assert(t, mock429.Mock.Request().Counter, 0) + return nil + }, + ), + }, + // Remove serviceTests from state + { + PreConfig: func() { + util.MockGetGroup( + "group_uid", + util.GeneratePaginatedResponse([]map[string]interface{}{util.StructToMap(util.GenerateGroupResponseGetModel("group_uid", "", ""))}), + 1, + ) + }, + Config: provider.ProviderConfig + ` + removed { + from = uxi_service_test.my_service_test + + lifecycle { + destroy = false + } + }`, + }, + // Delete testing automatically occurs in TestCase + }, + }) + + mockOAuth.Mock.Disable() +} diff --git a/pkg/config-api-provider/test/util/utils.go b/pkg/config-api-provider/test/util/utils.go index ff5a68ed..c14397d1 100644 --- a/pkg/config-api-provider/test/util/utils.go +++ b/pkg/config-api-provider/test/util/utils.go @@ -163,11 +163,13 @@ func GenerateNetworkGroupAssignmentGetResponse(uid string, postfix string) map[s } } -func GenerateServiceTestGroupAssignmentResponse(uid string, postfix string) resources.ServiceTestGroupAssignmentResponseModel { - return resources.ServiceTestGroupAssignmentResponseModel{ - UID: uid, - GroupUID: "group_uid" + postfix, - ServiceTestUID: "service_test_uid" + postfix, +func GenerateServiceTestGroupAssignmentResponse(uid string, postfix string) config_api_client.ServiceTestGroupAssignmentsPostResponse { + resourceType := "uxi/service-test-group-assignment" + return config_api_client.ServiceTestGroupAssignmentsPostResponse{ + Id: uid, + Group: *config_api_client.NewGroup("group_uid" + postfix), + ServiceTest: *config_api_client.NewServiceTest("service_test_uid" + postfix), + Type: &resourceType, } } @@ -300,6 +302,16 @@ func MockDeleteNetworkGroupAssignment(uid string, times int) { Reply(204) } +func MockPostServiceTestGroupAssignment(uid string, response map[string]interface{}, times int) { + gock.New("https://test.api.capenetworks.com"). + Post("/uxi/v1alpha1/service-test-group-assignments"). + MatchHeader("Content-Type", "application/json"). + MatchHeader("Authorization", "mock_token"). + Times(times). + Reply(200). + JSON(response) +} + var RateLimitingHeaders = map[string]string{ "X-RateLimit-Limit": "100", "X-RateLimit-Remaining": "0",