-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1685 from ctiwald/master
provider/aws: Implement support for various AWS ELB cookie stickiness policies
- Loading branch information
Showing
8 changed files
with
679 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
156 changes: 156 additions & 0 deletions
156
builtin/providers/aws/resource_aws_app_cookie_stickiness_policy.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/awslabs/aws-sdk-go/aws" | ||
"github.com/awslabs/aws-sdk-go/service/elb" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsAppCookieStickinessPolicy() *schema.Resource { | ||
return &schema.Resource{ | ||
// There is no concept of "updating" an App Stickiness policy in | ||
// the AWS API. | ||
Create: resourceAwsAppCookieStickinessPolicyCreate, | ||
Update: resourceAwsAppCookieStickinessPolicyCreate, | ||
|
||
Read: resourceAwsAppCookieStickinessPolicyRead, | ||
Delete: resourceAwsAppCookieStickinessPolicyDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"load_balancer": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"lb_port": &schema.Schema{ | ||
Type: schema.TypeInt, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"cookie_name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsAppCookieStickinessPolicyCreate(d *schema.ResourceData, meta interface{}) error { | ||
elbconn := meta.(*AWSClient).elbconn | ||
|
||
// Provision the AppStickinessPolicy | ||
acspOpts := &elb.CreateAppCookieStickinessPolicyInput{ | ||
CookieName: aws.String(d.Get("cookie_name").(string)), | ||
LoadBalancerName: aws.String(d.Get("load_balancer").(string)), | ||
PolicyName: aws.String(d.Get("name").(string)), | ||
} | ||
|
||
if _, err := elbconn.CreateAppCookieStickinessPolicy(acspOpts); err != nil { | ||
return fmt.Errorf("Error creating AppCookieStickinessPolicy: %s", err) | ||
} | ||
|
||
setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ | ||
LoadBalancerName: aws.String(d.Get("load_balancer").(string)), | ||
LoadBalancerPort: aws.Long(int64(d.Get("lb_port").(int))), | ||
PolicyNames: []*string{aws.String(d.Get("name").(string))}, | ||
} | ||
|
||
if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil { | ||
return fmt.Errorf("Error setting AppCookieStickinessPolicy: %s", err) | ||
} | ||
|
||
d.SetId(fmt.Sprintf("%s:%d:%s", | ||
*acspOpts.LoadBalancerName, | ||
*setLoadBalancerOpts.LoadBalancerPort, | ||
*acspOpts.PolicyName)) | ||
return nil | ||
} | ||
|
||
func resourceAwsAppCookieStickinessPolicyRead(d *schema.ResourceData, meta interface{}) error { | ||
elbconn := meta.(*AWSClient).elbconn | ||
|
||
lbName, lbPort, policyName := resourceAwsAppCookieStickinessPolicyParseId(d.Id()) | ||
|
||
request := &elb.DescribeLoadBalancerPoliciesInput{ | ||
LoadBalancerName: aws.String(lbName), | ||
PolicyNames: []*string{aws.String(policyName)}, | ||
} | ||
|
||
getResp, err := elbconn.DescribeLoadBalancerPolicies(request) | ||
if err != nil { | ||
if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "PolicyNotFound" { | ||
// The policy is gone. | ||
d.SetId("") | ||
return nil | ||
} | ||
return fmt.Errorf("Error retrieving policy: %s", err) | ||
} | ||
|
||
if len(getResp.PolicyDescriptions) != 1 { | ||
return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions) | ||
} | ||
|
||
// We can get away with this because there's only one attribute, the | ||
// cookie expiration, in these descriptions. | ||
policyDesc := getResp.PolicyDescriptions[0] | ||
cookieAttr := policyDesc.PolicyAttributeDescriptions[0] | ||
if *cookieAttr.AttributeName != "CookieName" { | ||
return fmt.Errorf("Unable to find cookie Name.") | ||
} | ||
d.Set("cookie_name", cookieAttr.AttributeValue) | ||
|
||
d.Set("name", policyName) | ||
d.Set("load_balancer", lbName) | ||
d.Set("lb_port", lbPort) | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsAppCookieStickinessPolicyDelete(d *schema.ResourceData, meta interface{}) error { | ||
elbconn := meta.(*AWSClient).elbconn | ||
|
||
lbName, _, policyName := resourceAwsAppCookieStickinessPolicyParseId(d.Id()) | ||
|
||
// Perversely, if we Set an empty list of PolicyNames, we detach the | ||
// policies attached to a listener, which is required to delete the | ||
// policy itself. | ||
setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ | ||
LoadBalancerName: aws.String(d.Get("load_balancer").(string)), | ||
LoadBalancerPort: aws.Long(int64(d.Get("lb_port").(int))), | ||
PolicyNames: []*string{}, | ||
} | ||
|
||
if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil { | ||
return fmt.Errorf("Error removing AppCookieStickinessPolicy: %s", err) | ||
} | ||
|
||
request := &elb.DeleteLoadBalancerPolicyInput{ | ||
LoadBalancerName: aws.String(lbName), | ||
PolicyName: aws.String(policyName), | ||
} | ||
|
||
if _, err := elbconn.DeleteLoadBalancerPolicy(request); err != nil { | ||
return fmt.Errorf("Error deleting App stickiness policy %s: %s", d.Id(), err) | ||
} | ||
return nil | ||
} | ||
|
||
// resourceAwsAppCookieStickinessPolicyParseId takes an ID and parses it into | ||
// it's constituent parts. You need three axes (LB name, policy name, and LB | ||
// port) to create or identify a stickiness policy in AWS's API. | ||
func resourceAwsAppCookieStickinessPolicyParseId(id string) (string, string, string) { | ||
parts := strings.SplitN(id, ":", 3) | ||
return parts[0], parts[1], parts[2] | ||
} |
125 changes: 125 additions & 0 deletions
125
builtin/providers/aws/resource_aws_app_cookie_stickiness_policy_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/awslabs/aws-sdk-go/aws" | ||
"github.com/awslabs/aws-sdk-go/service/elb" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccAWSAppCookieStickinessPolicy(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAppCookieStickinessPolicyDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccAppCookieStickinessPolicyConfig, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAppCookieStickinessPolicy( | ||
"aws_elb.lb", | ||
"aws_app_cookie_stickiness_policy.foo", | ||
), | ||
), | ||
}, | ||
resource.TestStep{ | ||
Config: testAccAppCookieStickinessPolicyConfigUpdate, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAppCookieStickinessPolicy( | ||
"aws_elb.lb", | ||
"aws_app_cookie_stickiness_policy.bar", | ||
), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckAppCookieStickinessPolicyDestroy(s *terraform.State) error { | ||
if len(s.RootModule().Resources) > 0 { | ||
return fmt.Errorf("Expected all resources to be gone, but found: %#v", s.RootModule().Resources) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testAccCheckAppCookieStickinessPolicy(elbResource string, policyResource string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[elbResource] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", elbResource) | ||
} | ||
|
||
if rs.Primary.ID == "" { | ||
return fmt.Errorf("No ID is set") | ||
} | ||
|
||
policy, ok := s.RootModule().Resources[policyResource] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", policyResource) | ||
} | ||
|
||
elbconn := testAccProvider.Meta().(*AWSClient).elbconn | ||
elbName, _, policyName := resourceAwsAppCookieStickinessPolicyParseId(policy.Primary.ID) | ||
_, err := elbconn.DescribeLoadBalancerPolicies(&elb.DescribeLoadBalancerPoliciesInput{ | ||
LoadBalancerName: aws.String(elbName), | ||
PolicyNames: []*string{aws.String(policyName)}, | ||
}) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
const testAccAppCookieStickinessPolicyConfig = ` | ||
resource "aws_elb" "lb" { | ||
name = "test-lb" | ||
availability_zones = ["us-east-1a"] | ||
listener { | ||
instance_port = 8000 | ||
instance_protocol = "http" | ||
lb_port = 80 | ||
lb_protocol = "http" | ||
} | ||
} | ||
resource "aws_app_cookie_stickiness_policy" "foo" { | ||
name = "foo_policy" | ||
load_balancer = "${aws_elb.lb}" | ||
lb_port = 80 | ||
cookie_name = "MyAppCookie" | ||
} | ||
` | ||
|
||
const testAccAppCookieStickinessPolicyConfigUpdate = ` | ||
resource "aws_elb" "lb" { | ||
name = "test-lb" | ||
availability_zones = ["us-east-1a"] | ||
listener { | ||
instance_port = 8000 | ||
instance_protocol = "http" | ||
lb_port = 80 | ||
lb_protocol = "http" | ||
} | ||
} | ||
resource "aws_app_cookie_stickiness_policy" "foo" { | ||
name = "foo_policy" | ||
load_balancer = "${aws_elb.lb}" | ||
lb_port = 80 | ||
cookie_name = "MyAppCookie" | ||
} | ||
resource "aws_app_cookie_stickiness_policy" "bar" { | ||
name = "bar_policy" | ||
load_balancer = "${aws_elb.lb}" | ||
lb_port = 80 | ||
cookie_name = "MyAppCookie" | ||
} | ||
` |
Oops, something went wrong.