Merge pull request #7188 from hashicorp/jbardin/GH-7017

provider/aws: Check for unassigned AWS Cookie Stickiness Policy
This commit is contained in:
James Bardin 2016-06-16 11:35:05 -04:00 committed by GitHub
commit f65a898a51
4 changed files with 158 additions and 1 deletions

View File

@ -2,7 +2,9 @@ package aws
import ( import (
"fmt" "fmt"
"log"
"regexp" "regexp"
"strconv"
"strings" "strings"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
@ -106,11 +108,22 @@ func resourceAwsAppCookieStickinessPolicyRead(d *schema.ResourceData, meta inter
} }
return fmt.Errorf("Error retrieving policy: %s", err) return fmt.Errorf("Error retrieving policy: %s", err)
} }
if len(getResp.PolicyDescriptions) != 1 { if len(getResp.PolicyDescriptions) != 1 {
return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions) 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 // We can get away with this because there's only one attribute, the
// cookie expiration, in these descriptions. // cookie expiration, in these descriptions.
policyDesc := getResp.PolicyDescriptions[0] policyDesc := getResp.PolicyDescriptions[0]
@ -127,6 +140,43 @@ func resourceAwsAppCookieStickinessPolicyRead(d *schema.ResourceData, meta inter
return nil 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 { func resourceAwsAppCookieStickinessPolicyDelete(d *schema.ResourceData, meta interface{}) error {
elbconn := meta.(*AWSClient).elbconn elbconn := meta.(*AWSClient).elbconn

View File

@ -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 { func testAccAppCookieStickinessPolicyConfig(rName string) string {
return fmt.Sprintf(` return fmt.Sprintf(`
resource "aws_elb" "lb" { resource "aws_elb" "lb" {

View File

@ -115,6 +115,18 @@ func resourceAwsLBCookieStickinessPolicyRead(d *schema.ResourceData, meta interf
return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions) 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 // We can get away with this because there's only one attribute, the
// cookie expiration, in these descriptions. // cookie expiration, in these descriptions.
policyDesc := getResp.PolicyDescriptions[0] policyDesc := getResp.PolicyDescriptions[0]

View File

@ -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 { func testAccLBCookieStickinessPolicyConfig(rName string) string {
return fmt.Sprintf(` return fmt.Sprintf(`
resource "aws_elb" "lb" { resource "aws_elb" "lb" {