Skip to content

Commit

Permalink
fix: handle 404 when reading user roles
Browse files Browse the repository at this point in the history
  • Loading branch information
johanneswuerbach committed Apr 29, 2024
1 parent ad50c39 commit c99642d
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 35 deletions.
22 changes: 6 additions & 16 deletions internal/provider/resource_application_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
52 changes: 52 additions & 0 deletions internal/provider/resource_application_user_test.go
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down Expand Up @@ -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" {
Expand Down
6 changes: 6 additions & 0 deletions internal/provider/resource_environment_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 7 additions & 19 deletions internal/provider/resource_environment_type_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
52 changes: 52 additions & 0 deletions internal/provider/resource_environment_type_user_test.go
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down Expand Up @@ -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" {
Expand Down
5 changes: 5 additions & 0 deletions internal/provider/resource_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c99642d

Please sign in to comment.