Skip to content

Commit

Permalink
r/aws_eks_access_policy_association: Tidy up and additional tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
ewbankkit committed Jan 18, 2024
1 parent fb7bef3 commit 152868a
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 107 deletions.
32 changes: 32 additions & 0 deletions internal/service/eks/access_entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,38 @@ func TestAccEKSAccessEntry_disappears(t *testing.T) {
})
}

func TestAccEKSAccessEntry_Disappears_cluster(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
t.Skip("skipping long-running test in short mode")
}

var accessentry types.AccessEntry
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_eks_access_entry.test"
clusterResourceName := "aws_eks_cluster.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
testAccPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, names.EKSEndpointID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckAccessEntryDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccAccessEntryConfig_basic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAccessEntryExists(ctx, resourceName, &accessentry),
acctest.CheckResourceDisappears(ctx, acctest.Provider, tfeks.ResourceCluster(), clusterResourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func TestAccEKSAccessEntry_tags(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
Expand Down
176 changes: 104 additions & 72 deletions internal/service/eks/access_policy_association.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ package eks

import (
"context"
"fmt"
"log"
"strings"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
Expand All @@ -18,6 +20,7 @@ import (
"github.com/hashicorp/terraform-provider-aws/internal/errs"
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
"github.com/hashicorp/terraform-provider-aws/internal/flex"
tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
)
Expand All @@ -28,6 +31,7 @@ func resourceAccessPolicyAssociation() *schema.Resource {
CreateWithoutTimeout: resourceAccessPolicyAssociationCreate,
ReadWithoutTimeout: resourceAccessPolicyAssociationRead,
DeleteWithoutTimeout: resourceAccessPolicyAssociationDelete,

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Expand All @@ -38,10 +42,6 @@ func resourceAccessPolicyAssociation() *schema.Resource {
},

Schema: map[string]*schema.Schema{
"associated_at": {
Type: schema.TypeString,
Computed: true,
},
"access_scope": {
Type: schema.TypeList,
MinItems: 1,
Expand All @@ -50,11 +50,6 @@ func resourceAccessPolicyAssociation() *schema.Resource {
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"namespaces": {
Type: schema.TypeSet,
Optional: true,
Expand All @@ -63,9 +58,18 @@ func resourceAccessPolicyAssociation() *schema.Resource {
Type: schema.TypeString,
},
},
"type": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
},
},
},
"associated_at": {
Type: schema.TypeString,
Computed: true,
},
"cluster_name": {
Type: schema.TypeString,
Required: true,
Expand Down Expand Up @@ -97,22 +101,23 @@ func resourceAccessPolicyAssociationCreate(ctx context.Context, d *schema.Resour
conn := meta.(*conns.AWSClient).EKSClient(ctx)

clusterName := d.Get("cluster_name").(string)
principal_arn := d.Get("principal_arn").(string)
policy_arn := d.Get("policy_arn").(string)
associateID := AssociatePolicyCreateResourceID(clusterName, principal_arn, policy_arn)
principalARN := d.Get("principal_arn").(string)
policyARN := d.Get("policy_arn").(string)
id := accessPolicyAssociationCreateResourceID(clusterName, principalARN, policyARN)
input := &eks.AssociateAccessPolicyInput{
ClusterName: aws.String(clusterName),
PrincipalArn: aws.String(principal_arn),
PolicyArn: aws.String(policy_arn),
AccessScope: expandAccessScope(d.Get("access_scope").([]interface{})),
ClusterName: aws.String(clusterName),
PolicyArn: aws.String(policyARN),
PrincipalArn: aws.String(principalARN),
}

_, err := conn.AssociateAccessPolicy(ctx, input)

if err != nil {
return sdkdiag.AppendErrorf(diags, "creating EKS Access Policy Association: %s", err)
return sdkdiag.AppendErrorf(diags, "creating EKS Access Policy Association (%s): %s", id, err)
}

d.SetId(associateID)
d.SetId(id)

return append(diags, resourceAccessPolicyAssociationRead(ctx, d, meta)...)
}
Expand All @@ -121,28 +126,19 @@ func resourceAccessPolicyAssociationRead(ctx context.Context, d *schema.Resource
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).EKSClient(ctx)

clusterName, principal_arn, policy_arn, err := AssociatePolicyParseResourceID(d.Id())
clusterName, principalARN, policyARN, err := accessPolicyAssociationParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendErrorf(diags, "reading EKS Associate Policy (%s): %s", d.Id(), err)
return sdkdiag.AppendFromErr(diags, err)
}
output, err := FindAccessPolicyByID(ctx, conn, clusterName, principal_arn, policy_arn)

output, err := findAccessPolicyAssociationByThreePartKey(ctx, conn, clusterName, principalARN, policyARN)

if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] EKS Access Policy Association (%s) not found, removing from state", d.Id())
d.SetId("")
return diags
}

if output == nil {
if d.IsNewResource() {
return sdkdiag.AppendErrorf(diags, "reading EKS Associated Policy Attachment (%s): not found after creation", d.Id())
}

log.Printf("[WARN] EKS Associated Policy Attachment (%s) not found, removing from state", d.Id())
d.SetId("")
return diags
}

if err != nil {
return sdkdiag.AppendErrorf(diags, "reading EKS Access Policy Association (%s): %s", d.Id(), err)
}
Expand All @@ -151,41 +147,107 @@ func resourceAccessPolicyAssociationRead(ctx context.Context, d *schema.Resource
d.Set("associated_at", aws.ToTime(output.AssociatedAt).String())
d.Set("cluster_name", clusterName)
d.Set("modified_at", aws.ToTime(output.ModifiedAt).String())
d.Set("policy_arn", policy_arn)
d.Set("principal_arn", principal_arn)
d.Set("policy_arn", policyARN)
d.Set("principal_arn", principalARN)

return diags
}

func resourceAccessPolicyAssociationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).EKSClient(ctx)
clusterName, principal_arn, policy_arn, err := AssociatePolicyParseResourceID(d.Id())

clusterName, principalARN, policyARN, err := accessPolicyAssociationParseResourceID(d.Id())
if err != nil {
return sdkdiag.AppendErrorf(diags, "deleting EKS Policy Association (%s): %s", d.Id(), err)
return sdkdiag.AppendFromErr(diags, err)
}

log.Printf("[DEBUG] Deleting EKS Policy Associaion: %s", d.Id())

input := &eks.DisassociateAccessPolicyInput{
log.Printf("[DEBUG] Deleting EKS Access Policy Association: %s", d.Id())
_, err = conn.DisassociateAccessPolicy(ctx, &eks.DisassociateAccessPolicyInput{
ClusterName: aws.String(clusterName),
PrincipalArn: aws.String(principal_arn),
PolicyArn: aws.String(policy_arn),
}
_, err = conn.DisassociateAccessPolicy(ctx, input)
PolicyArn: aws.String(policyARN),
PrincipalArn: aws.String(principalARN),
})

if errs.IsA[*types.ResourceNotFoundException](err) {
return diags
}

if err != nil {
return sdkdiag.AppendErrorf(diags, "deleting EKS Policy Associattion (%s): %s", d.Id(), err)
return sdkdiag.AppendErrorf(diags, "deleting EKS Access Policy Association (%s): %s", d.Id(), err)
}

return diags
}

const accessPolicyAssociationResourceIDSeparator = "#"

func accessPolicyAssociationCreateResourceID(clusterName, principalARN, policyARN string) string {
parts := []string{clusterName, principalARN, policyARN}
id := strings.Join(parts, accessPolicyAssociationResourceIDSeparator)

return id
}

func accessPolicyAssociationParseResourceID(id string) (string, string, string, error) {
parts := strings.SplitN(id, accessPolicyAssociationResourceIDSeparator, 3)

if len(parts) == 3 && parts[0] != "" && parts[1] != "" && parts[2] != "" {
return parts[0], parts[1], parts[2], nil
}

return "", "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected cluster-name%[2]sprincipal-arn%[2]spolicy-arn", id, accessPolicyAssociationResourceIDSeparator)
}

func findAccessPolicyAssociationByThreePartKey(ctx context.Context, conn *eks.Client, clusterName, principalARN, policyARN string) (*types.AssociatedAccessPolicy, error) {
input := &eks.ListAssociatedAccessPoliciesInput{
ClusterName: aws.String(clusterName),
PrincipalArn: aws.String(principalARN),
}

return findAssociatedAccessPolicy(ctx, conn, input, func(v *types.AssociatedAccessPolicy) bool {
return aws.ToString(v.PolicyArn) == policyARN
})
}

func findAssociatedAccessPolicy(ctx context.Context, conn *eks.Client, input *eks.ListAssociatedAccessPoliciesInput, filter tfslices.Predicate[*types.AssociatedAccessPolicy]) (*types.AssociatedAccessPolicy, error) {
output, err := findAssociatedAccessPolicies(ctx, conn, input, filter)

if err != nil {
return nil, err
}

return tfresource.AssertSingleValueResult(output)
}

func findAssociatedAccessPolicies(ctx context.Context, conn *eks.Client, input *eks.ListAssociatedAccessPoliciesInput, filter tfslices.Predicate[*types.AssociatedAccessPolicy]) ([]types.AssociatedAccessPolicy, error) {
var output []types.AssociatedAccessPolicy

pages := eks.NewListAssociatedAccessPoliciesPaginator(conn, input)
for pages.HasMorePages() {
page, err := pages.NextPage(ctx)

if errs.IsA[*types.ResourceNotFoundException](err) {
return nil, &retry.NotFoundError{
LastError: err,
LastRequest: input,
}
}

if err != nil {
return nil, err
}

for _, v := range page.AssociatedAccessPolicies {
if filter(&v) {
output = append(output, v)
}
}
}

return output, nil
}

func expandAccessScope(l []interface{}) *types.AccessScope {
if len(l) == 0 {
return nil
Expand Down Expand Up @@ -218,33 +280,3 @@ func flattenAccessScope(apiObject *types.AccessScope) []interface{} {

return []interface{}{tfMap}
}

func FindAccessPolicyByID(ctx context.Context, conn *eks.Client, clusterName, principalARN, policyARN string) (*types.AssociatedAccessPolicy, error) {
input := &eks.ListAssociatedAccessPoliciesInput{
ClusterName: aws.String(clusterName),
PrincipalArn: aws.String(principalARN),
}

var result *types.AssociatedAccessPolicy

output, err := conn.ListAssociatedAccessPolicies(ctx, input)
if output == nil || output.AssociatedAccessPolicies == nil || errs.IsA[*types.ResourceNotFoundException](err) {
return nil, &retry.NotFoundError{
Message: "Empty result",
LastRequest: input,
}
}

if err != nil {
return nil, err
}

for _, v := range output.AssociatedAccessPolicies {
v := v
if aws.ToString(v.PolicyArn) == policyARN {
result = &v
}
}

return result, nil
}
Loading

0 comments on commit 152868a

Please sign in to comment.