Skip to content

Commit

Permalink
Merge pull request #7188 from hashicorp/jbardin/GH-7017
Browse files Browse the repository at this point in the history
provider/aws: Check for unassigned AWS Cookie Stickiness Policy
  • Loading branch information
jbardin authored Jun 16, 2016
2 parents 24bcac4 + cfd8254 commit f65a898
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package aws

import (
"fmt"
"log"
"regexp"
"strconv"
"strings"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -106,11 +108,22 @@ func resourceAwsAppCookieStickinessPolicyRead(d *schema.ResourceData, meta inter
}
return fmt.Errorf("Error retrieving policy: %s", err)
}

if len(getResp.PolicyDescriptions) != 1 {
return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions)
}

// we know the policy exists now, but we have to check if it's assigned to a listener
assigned, err := resourceAwsELBSticknessPolicyAssigned(policyName, lbName, lbPort, elbconn)
if err != nil {
return err
}
if !assigned {
// policy exists, but isn't assigned to a listener
log.Printf("[DEBUG] policy '%s' exists, but isn't assigned to a listener", policyName)
d.SetId("")
return nil
}

// We can get away with this because there's only one attribute, the
// cookie expiration, in these descriptions.
policyDesc := getResp.PolicyDescriptions[0]
Expand All @@ -127,6 +140,43 @@ func resourceAwsAppCookieStickinessPolicyRead(d *schema.ResourceData, meta inter
return nil
}

// Determine if a particular policy is assigned to an ELB listener
func resourceAwsELBSticknessPolicyAssigned(policyName, lbName, lbPort string, elbconn *elb.ELB) (bool, error) {
describeElbOpts := &elb.DescribeLoadBalancersInput{
LoadBalancerNames: []*string{aws.String(lbName)},
}
describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts)
if err != nil {
if ec2err, ok := err.(awserr.Error); ok {
if ec2err.Code() == "LoadBalancerNotFound" {
return false, nil
}
}
return false, fmt.Errorf("Error retrieving ELB description: %s", err)
}

if len(describeResp.LoadBalancerDescriptions) != 1 {
return false, fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancerDescriptions)
}

lb := describeResp.LoadBalancerDescriptions[0]
assigned := false
for _, listener := range lb.ListenerDescriptions {
if lbPort != strconv.Itoa(int(*listener.Listener.LoadBalancerPort)) {
continue
}

for _, name := range listener.PolicyNames {
if policyName == *name {
assigned = true
break
}
}
}

return assigned, nil
}

func resourceAwsAppCookieStickinessPolicyDelete(d *schema.ResourceData, meta interface{}) error {
elbconn := meta.(*AWSClient).elbconn

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,54 @@ func testAccCheckAppCookieStickinessPolicy(elbResource string, policyResource st
}
}

// ensure the policy is re-added is it goes missing
func TestAccAWSAppCookieStickinessPolicy_drift(t *testing.T) {
lbName := fmt.Sprintf("tf-test-lb-%s", acctest.RandString(5))

// We only want to remove the reference to the policy from the listner,
// beacause that's all that can be done via the console.
removePolicy := func() {
conn := testAccProvider.Meta().(*AWSClient).elbconn

setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
LoadBalancerName: aws.String(lbName),
LoadBalancerPort: aws.Int64(80),
PolicyNames: []*string{},
}

if _, err := conn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil {
t.Fatalf("Error removing AppCookieStickinessPolicy: %s", err)
}
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAppCookieStickinessPolicyDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAppCookieStickinessPolicyConfig(lbName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAppCookieStickinessPolicy(
"aws_elb.lb",
"aws_app_cookie_stickiness_policy.foo",
),
),
},
resource.TestStep{
PreConfig: removePolicy,
Config: testAccAppCookieStickinessPolicyConfig(lbName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAppCookieStickinessPolicy(
"aws_elb.lb",
"aws_app_cookie_stickiness_policy.foo",
),
),
},
},
})
}

func testAccAppCookieStickinessPolicyConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_elb" "lb" {
Expand Down
12 changes: 12 additions & 0 deletions builtin/providers/aws/resource_aws_lb_cookie_stickiness_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ func resourceAwsLBCookieStickinessPolicyRead(d *schema.ResourceData, meta interf
return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions)
}

// we know the policy exists now, but we have to check if it's assigned to a listener
assigned, err := resourceAwsELBSticknessPolicyAssigned(policyName, lbName, lbPort, elbconn)
if err != nil {
return err
}
if !assigned {
// policy exists, but isn't assigned to a listener
log.Printf("[DEBUG] policy '%s' exists, but isn't assigned to a listener", policyName)
d.SetId("")
return nil
}

// We can get away with this because there's only one attribute, the
// cookie expiration, in these descriptions.
policyDesc := getResp.PolicyDescriptions[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,53 @@ func testAccCheckLBCookieStickinessPolicy(elbResource string, policyResource str
}
}

func TestAccCheckLBCookieStickinessPolicy_drift(t *testing.T) {
lbName := fmt.Sprintf("tf-test-lb-%s", acctest.RandString(5))

// We only want to remove the reference to the policy from the listner,
// beacause that's all that can be done via the console.
removePolicy := func() {
conn := testAccProvider.Meta().(*AWSClient).elbconn

setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
LoadBalancerName: aws.String(lbName),
LoadBalancerPort: aws.Int64(80),
PolicyNames: []*string{},
}

if _, err := conn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil {
t.Fatalf("Error removing LBCookieStickinessPolicy: %s", err)
}
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckLBCookieStickinessPolicyDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccLBCookieStickinessPolicyConfig(lbName),
Check: resource.ComposeTestCheckFunc(
testAccCheckLBCookieStickinessPolicy(
"aws_elb.lb",
"aws_lb_cookie_stickiness_policy.foo",
),
),
},
resource.TestStep{
PreConfig: removePolicy,
Config: testAccLBCookieStickinessPolicyConfig(lbName),
Check: resource.ComposeTestCheckFunc(
testAccCheckLBCookieStickinessPolicy(
"aws_elb.lb",
"aws_lb_cookie_stickiness_policy.foo",
),
),
},
},
})
}

func testAccLBCookieStickinessPolicyConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_elb" "lb" {
Expand Down

0 comments on commit f65a898

Please sign in to comment.