diff --git a/internal/provider/resource_application_user.go b/internal/provider/resource_application_user.go index 2e1aab6..4359cbc 100644 --- a/internal/provider/resource_application_user.go +++ b/internal/provider/resource_application_user.go @@ -175,23 +175,8 @@ func (r *ResourceApplicationUser) Read(ctx context.Context, req resource.ReadReq } var httpResp *client.GetUserRoleInAppResponse - err := retry.RetryContext(ctx, defaultApplicationUserReadTimeout, func() *retry.RetryError { - var err error - httpResp, err = r.client.GetUserRoleInAppWithResponse(ctx, r.orgId, data.AppID.ValueString(), data.UserID.ValueString()) - if err != nil { - return retry.NonRetryableError(err) - } - if httpResp.StatusCode() == 404 { - return retry.RetryableError(fmt.Errorf("waiting for application to be ready, status code: %d, body: %s", httpResp.StatusCode(), httpResp.Body)) - } - - if httpResp.StatusCode() != 200 { - return retry.NonRetryableError(fmt.Errorf("unable to read resource application user, unexpected status code: %d, body: %s", httpResp.StatusCode(), httpResp.Body)) - } - - return nil - }) + httpResp, err := r.client.GetUserRoleInAppWithResponse(ctx, r.orgId, data.AppID.ValueString(), data.UserID.ValueString()) if err != nil { resp.Diagnostics.AddError(HUM_CLIENT_ERR, fmt.Sprintf("Unable to read resource application user, got error: %s", err)) return @@ -203,6 +188,11 @@ func (r *ResourceApplicationUser) Read(ctx context.Context, req resource.ReadReq return } + if httpResp.StatusCode() != 200 { + resp.Diagnostics.AddError(HUM_API_ERR, fmt.Sprintf("Unable to get application user, unexpected status code: %d, body: %s", httpResp.StatusCode(), httpResp.Body)) + return + } + data.Role = types.StringValue(httpResp.JSON200.Role) // Save updated data into Terraform state diff --git a/internal/provider/resource_application_user_test.go b/internal/provider/resource_application_user_test.go index a93930d..cae4561 100644 --- a/internal/provider/resource_application_user_test.go +++ b/internal/provider/resource_application_user_test.go @@ -1,12 +1,16 @@ package provider import ( + "context" "fmt" + "os" "testing" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/humanitec/humanitec-go-autogen" + "github.com/stretchr/testify/assert" ) func TestAccResourceApplicationUser(t *testing.T) { @@ -46,6 +50,54 @@ func TestAccResourceApplicationUser(t *testing.T) { }) } +func TestAccResourceApplicationUserDeletedManually(t *testing.T) { + assert := assert.New(t) + ctx := context.Background() + id := fmt.Sprintf("app-user-test-%d", time.Now().UnixNano()) + testUserID := "1b305f15-f18f-4357-8311-01f88ed99d1b" + + orgID := os.Getenv("HUMANITEC_ORG") + token := os.Getenv("HUMANITEC_TOKEN") + + var client *humanitec.Client + var err error + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + + client, err = NewHumanitecClient(humanitec.DefaultAPIHost, token, "test", nil) + assert.NoError(err) + }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read testing + { + Config: testAccResourceApplicationUser(id, testUserID, "owner"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("humanitec_application_user.another_user", "id", fmt.Sprintf("%s/%s", id, testUserID)), + resource.TestCheckResourceAttr("humanitec_application_user.another_user", "role", "owner"), + func(_ *terraform.State) error { + // Manually delete the application via the API + resp, err := client.DeleteApplicationWithResponse(ctx, orgID, id) + if err != nil { + return err + } + + if resp.StatusCode() != 204 { + return fmt.Errorf("expected status code 204, got %d, body: %s", resp.StatusCode(), string(resp.Body)) + } + + return nil + }, + ), + ExpectNonEmptyPlan: true, + }, + // Delete testing automatically occurs in TestCase + }, + }) +} + func testAccResourceApplicationUser(id, userID, role string) string { return fmt.Sprintf(` resource "humanitec_application" "app_user_test" { diff --git a/internal/provider/resource_environment_type.go b/internal/provider/resource_environment_type.go index b7a28b4..c55c089 100644 --- a/internal/provider/resource_environment_type.go +++ b/internal/provider/resource_environment_type.go @@ -136,6 +136,12 @@ func (r *ResourceEnvironmentType) Read(ctx context.Context, req resource.ReadReq return } + if httpResp.StatusCode() == 404 { + resp.Diagnostics.AddWarning("Environment Type not found", fmt.Sprintf("The environment type (%s) was deleted outside Terraform", data.ID.ValueString())) + resp.State.RemoveResource(ctx) + return + } + if httpResp.StatusCode() != 200 { resp.Diagnostics.AddError(HUM_API_ERR, fmt.Sprintf("Unable to read environment type, unexpected status code: %d, body: %s", httpResp.StatusCode(), httpResp.Body)) return diff --git a/internal/provider/resource_environment_type_user.go b/internal/provider/resource_environment_type_user.go index 19d6bf0..ae3d6bb 100644 --- a/internal/provider/resource_environment_type_user.go +++ b/internal/provider/resource_environment_type_user.go @@ -174,35 +174,23 @@ func (r *ResourceEnvironmentTypeUser) Read(ctx context.Context, req resource.Rea return } - var httpResp *client.GetUserRoleInEnvTypeResponse - err := retry.RetryContext(ctx, defaultEnvironmentTypeUserReadTimeout, func() *retry.RetryError { - var err error - httpResp, err = r.client.GetUserRoleInEnvTypeWithResponse(ctx, r.orgId, data.EnvTypeID.ValueString(), data.UserID.ValueString()) - if err != nil { - return retry.NonRetryableError(err) - } - - if httpResp.StatusCode() == 404 { - return retry.RetryableError(fmt.Errorf("waiting for application to be ready, status code: %d, body: %s", httpResp.StatusCode(), httpResp.Body)) - } - - if httpResp.StatusCode() != 200 { - return retry.NonRetryableError(fmt.Errorf("unable to read resource environment type user, unexpected status code: %d, body: %s", httpResp.StatusCode(), httpResp.Body)) - } - - return nil - }) + httpResp, err := r.client.GetUserRoleInEnvTypeWithResponse(ctx, r.orgId, data.EnvTypeID.ValueString(), data.UserID.ValueString()) if err != nil { resp.Diagnostics.AddError(HUM_CLIENT_ERR, fmt.Sprintf("Unable to read resource environment type user, got error: %s", err)) return } if httpResp.StatusCode() == 404 { - resp.Diagnostics.AddWarning("Application user not found", fmt.Sprintf("The application user (%s) was deleted outside Terraform", data.ID.ValueString())) + resp.Diagnostics.AddWarning("Environment Type user not found", fmt.Sprintf("The environment type user (%s) was deleted outside Terraform", data.ID.ValueString())) resp.State.RemoveResource(ctx) return } + if httpResp.StatusCode() != 200 { + resp.Diagnostics.AddError(HUM_API_ERR, fmt.Sprintf("Unable to get environment type user, unexpected status code: %d, body: %s", httpResp.StatusCode(), httpResp.Body)) + return + } + data.Role = types.StringValue(httpResp.JSON200.Role) // Save updated data into Terraform state diff --git a/internal/provider/resource_environment_type_user_test.go b/internal/provider/resource_environment_type_user_test.go index 1496e27..0a74097 100644 --- a/internal/provider/resource_environment_type_user_test.go +++ b/internal/provider/resource_environment_type_user_test.go @@ -1,12 +1,16 @@ package provider import ( + "context" "fmt" + "os" "testing" "time" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/humanitec/humanitec-go-autogen" + "github.com/stretchr/testify/assert" ) func TestAccResourceEnvironmentTypeUser(t *testing.T) { @@ -47,6 +51,54 @@ func TestAccResourceEnvironmentTypeUser(t *testing.T) { }) } +func TestAccResourceEnvironmentTypeUserDeletedManually(t *testing.T) { + assert := assert.New(t) + ctx := context.Background() + id := fmt.Sprintf("env-type-user-test-%d", time.Now().UnixNano()) + testUserID := "c0725726-0613-43d4-8398-907d07fba2e4" + + orgID := os.Getenv("HUMANITEC_ORG") + token := os.Getenv("HUMANITEC_TOKEN") + + var client *humanitec.Client + var err error + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + + client, err = NewHumanitecClient(humanitec.DefaultAPIHost, token, "test", nil) + assert.NoError(err) + }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read testing + { + Config: testAccResourceEnvironmentTypeUser(id, testUserID, "deployer"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("humanitec_environment_type_user.another_user", "id", fmt.Sprintf("%s/%s", id, testUserID)), + resource.TestCheckResourceAttr("humanitec_environment_type_user.another_user", "role", "deployer"), + func(_ *terraform.State) error { + // Manually delete the application via the API + resp, err := client.DeleteEnvironmentTypeWithResponse(ctx, orgID, id) + if err != nil { + return err + } + + if resp.StatusCode() != 204 { + return fmt.Errorf("expected status code 204, got %d, body: %s", resp.StatusCode(), string(resp.Body)) + } + + return nil + }, + ), + ExpectNonEmptyPlan: true, + }, + // Delete testing automatically occurs in TestCase + }, + }) +} + func testAccResourceEnvironmentTypeUser(id, userID, role string) string { return fmt.Sprintf(` resource "humanitec_environment_type" "qa" { diff --git a/internal/provider/resource_user.go b/internal/provider/resource_user.go index 732d811..2df5b95 100644 --- a/internal/provider/resource_user.go +++ b/internal/provider/resource_user.go @@ -167,6 +167,11 @@ func (r *ResourceUser) Read(ctx context.Context, req resource.ReadRequest, resp resp.Diagnostics.AddError(HUM_CLIENT_ERR, fmt.Sprintf("Unable to read user, got error: %s", err)) return } + if httpResp.StatusCode() == 404 { + resp.Diagnostics.AddWarning("User not found", fmt.Sprintf("The user (%s) was deleted outside Terraform", data.ID.ValueString())) + resp.State.RemoveResource(ctx) + return + } if httpResp.StatusCode() != 200 { resp.Diagnostics.AddError(HUM_API_ERR, fmt.Sprintf("Unable to read user, unexpected status code: %d, body: %s", httpResp.StatusCode(), httpResp.Body)) return