diff --git a/internal/provider/resources/resource_api_token.go b/internal/provider/resources/resource_api_token.go index 5dfa78af..934a1edb 100644 --- a/internal/provider/resources/resource_api_token.go +++ b/internal/provider/resources/resource_api_token.go @@ -27,7 +27,6 @@ import ( var _ resource.Resource = &ApiTokenResource{} var _ resource.ResourceWithImportState = &ApiTokenResource{} var _ resource.ResourceWithConfigure = &ApiTokenResource{} -var _ resource.ResourceWithValidateConfig = &ApiTokenResource{} func NewApiTokenResource() resource.Resource { return &ApiTokenResource{} @@ -136,6 +135,13 @@ func (r *ApiTokenResource) Create( return } + // Validate roles + diags = r.ValidateApiTokenRoles(data.Type.ValueString(), roles) + if diags != nil { + resp.Diagnostics.Append(diags...) + return + } + // Create the API token request createApiTokenRequest := iam.CreateApiTokenRequest{ Name: data.Name.ValueString(), @@ -349,6 +355,13 @@ func (r *ApiTokenResource) Update( return } + // Validate roles + diags = r.ValidateApiTokenRoles(data.Type.ValueString(), roles) + if diags != nil { + resp.Diagnostics.Append(diags...) + return + } + // Update API token roles updateApiTokenRolesRequest := iam.UpdateApiTokenRolesRequest{ Roles: roles, @@ -478,49 +491,6 @@ func (r *ApiTokenResource) ImportState( resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) } -func (r *ApiTokenResource) ValidateConfig( - ctx context.Context, - req resource.ValidateConfigRequest, - resp *resource.ValidateConfigResponse, -) { - var data models.ApiTokenResource - - resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - // Convert Terraform set of roles to API token roles - roles, diags := RequestApiTokenRoles(ctx, data.Roles) - if diags.HasError() { - resp.Diagnostics.Append(diags...) - return - } - - tokenRole, diags := RequestApiTokenPrimaryRole(roles, data.Type.ValueString()) - if diags != nil { - resp.Diagnostics.Append(diags...) - return - } - - entityType := data.Type.ValueString() - - // Check if the role is valid for the token entity type - if !common.ValidateRoleMatchesEntityType(tokenRole.Role, entityType) { - resp.Diagnostics.AddError( - fmt.Sprintf("Role '%s' is not valid for token type '%s'", tokenRole.Role, entityType), - fmt.Sprintf("Please provide a valid role for the entity type '%s'", entityType), - ) - return - } - - diags = r.ValidateApiTokenRoles(entityType, roles) - if diags != nil { - resp.Diagnostics.Append(diags...) - return - } -} - func (r *ApiTokenResource) ValidateApiTokenRoles(entityType string, roles []iam.ApiTokenRole) diag.Diagnostics { var numRolesMatchingEntityType int var invalidRoleError string @@ -547,8 +517,8 @@ func (r *ApiTokenResource) ValidateApiTokenRoles(entityType string, roles []iam. if !common.ValidateRoleMatchesEntityType(role.Role, string(role.EntityType)) { return diag.Diagnostics{ diag.NewErrorDiagnostic( - fmt.Sprintf("Role '%s' is not valid for entity type '%s'", role.Role, role.EntityType), - fmt.Sprintf("Please provide a valid role for the entity type '%s'", role.EntityType), + fmt.Sprintf("Role '%s' is not valid for token type '%s'", role.Role, role.EntityType), + fmt.Sprintf("Please provide a valid role for the token type '%s'", role.EntityType), ), } } diff --git a/internal/provider/resources/resource_api_token_test.go b/internal/provider/resources/resource_api_token_test.go index f1f72ec2..10375ae4 100644 --- a/internal/provider/resources/resource_api_token_test.go +++ b/internal/provider/resources/resource_api_token_test.go @@ -35,7 +35,7 @@ func TestAcc_ResourceOrganizationApiToken(t *testing.T) { ProtoV6ProviderFactories: astronomerprovider.TestAccProtoV6ProviderFactories, PreCheck: func() { astronomerprovider.TestAccPreCheck(t) }, CheckDestroy: resource.ComposeTestCheckFunc( - // Check that the organization api token has been removed + // Check that the api token has been removed testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, organization: true, shouldExist: false}), ), Steps: []resource.TestStep{ @@ -196,7 +196,7 @@ func TestAcc_ResourceOrganizationApiToken(t *testing.T) { resource.TestCheckResourceAttr(resourceVar, "roles.2.entity_id", deploymentId), resource.TestCheckResourceAttr(resourceVar, "roles.2.entity_type", string(iam.DEPLOYMENT)), resource.TestCheckResourceAttr(resourceVar, "roles.2.role", "DEPLOYMENT_ADMIN"), - // Check via API that organization api token exists + // Check via API that api token exists testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, organization: true, shouldExist: true}), ), }, @@ -227,7 +227,7 @@ func TestAcc_ResourceOrganizationApiToken(t *testing.T) { }), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceVar, "description", "new description"), - // Check via API that organization api token exists + // Check via API that api token exists testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, organization: true, shouldExist: true}), ), }, @@ -310,7 +310,7 @@ func TestAcc_ResourceOrganizationApiToken(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceVar, "type", string(iam.ORGANIZATION)), resource.TestCheckResourceAttr(resourceVar, "description", utils.TestResourceDescription), - // Check via API that organization api token exists + // Check via API that api token exists testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, organization: true, shouldExist: true}), ), }, @@ -339,7 +339,7 @@ func TestAcc_ResourceWorkspaceApiToken(t *testing.T) { ProtoV6ProviderFactories: astronomerprovider.TestAccProtoV6ProviderFactories, PreCheck: func() { astronomerprovider.TestAccPreCheck(t) }, CheckDestroy: resource.ComposeTestCheckFunc( - // Check that the organization api token has been removed + // Check that the api token has been removed testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, workspace: true, shouldExist: false}), ), Steps: []resource.TestStep{ @@ -467,7 +467,7 @@ func TestAcc_ResourceWorkspaceApiToken(t *testing.T) { resource.TestCheckResourceAttr(resourceVar, "roles.1.entity_id", deploymentId), resource.TestCheckResourceAttr(resourceVar, "roles.1.entity_type", string(iam.DEPLOYMENT)), resource.TestCheckResourceAttr(resourceVar, "roles.1.role", "DEPLOYMENT_ADMIN"), - // Check via API that organization api token exists + // Check via API that api token exists testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, workspace: true, shouldExist: true}), ), }, @@ -493,7 +493,7 @@ func TestAcc_ResourceWorkspaceApiToken(t *testing.T) { }), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceVar, "description", "new description"), - // Check via API that organization api token exists + // Check via API that api token exists testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, workspace: true, shouldExist: true}), ), }, @@ -544,7 +544,7 @@ func TestAcc_ResourceWorkspaceApiToken(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceVar, "type", string(iam.WORKSPACE)), resource.TestCheckResourceAttr(resourceVar, "description", utils.TestResourceDescription), - // Check via API that organization api token exists + // Check via API that api token exists testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, workspace: true, shouldExist: true}), ), }, @@ -573,7 +573,7 @@ func TestAcc_ResourceDeploymentApiToken(t *testing.T) { ProtoV6ProviderFactories: astronomerprovider.TestAccProtoV6ProviderFactories, PreCheck: func() { astronomerprovider.TestAccPreCheck(t) }, CheckDestroy: resource.ComposeTestCheckFunc( - // Check that the organization api token has been removed + // Check that the api token has been removed testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, deployment: true, shouldExist: false}), ), Steps: []resource.TestStep{ @@ -668,7 +668,7 @@ func TestAcc_ResourceDeploymentApiToken(t *testing.T) { resource.TestCheckResourceAttr(resourceVar, "roles.0.entity_id", deploymentId), resource.TestCheckResourceAttr(resourceVar, "roles.0.entity_type", string(iam.DEPLOYMENT)), resource.TestCheckResourceAttr(resourceVar, "roles.0.role", "DEPLOYMENT_ADMIN"), - // Check via API that organization api token exists + // Check via API that api token exists testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, deployment: true, shouldExist: true}), ), }, @@ -689,7 +689,7 @@ func TestAcc_ResourceDeploymentApiToken(t *testing.T) { }), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceVar, "description", "new description"), - // Check via API that organization api token exists + // Check via API that api token exists testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, deployment: true, shouldExist: true}), ), }, @@ -736,7 +736,7 @@ func TestAcc_ResourceDeploymentApiToken(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceVar, "type", string(iam.DEPLOYMENT)), resource.TestCheckResourceAttr(resourceVar, "description", utils.TestResourceDescription), - // Check via API that organization api token exists + // Check via API that api token exists testAccCheckApiTokenExistence(t, checkApiTokensExistenceInput{name: apiTokenName, deployment: true, shouldExist: true}), ), },