github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_lb_ssl_negotiation_policy.go (about) 1 package aws 2 3 import ( 4 "bytes" 5 "fmt" 6 "log" 7 "strings" 8 9 "github.com/aws/aws-sdk-go/aws" 10 "github.com/aws/aws-sdk-go/aws/awserr" 11 "github.com/aws/aws-sdk-go/service/elb" 12 "github.com/hashicorp/terraform/helper/hashcode" 13 "github.com/hashicorp/terraform/helper/schema" 14 ) 15 16 func resourceAwsLBSSLNegotiationPolicy() *schema.Resource { 17 return &schema.Resource{ 18 // There is no concept of "updating" an LB policy in 19 // the AWS API. 20 Create: resourceAwsLBSSLNegotiationPolicyCreate, 21 Read: resourceAwsLBSSLNegotiationPolicyRead, 22 Delete: resourceAwsLBSSLNegotiationPolicyDelete, 23 24 Schema: map[string]*schema.Schema{ 25 "name": &schema.Schema{ 26 Type: schema.TypeString, 27 Required: true, 28 ForceNew: true, 29 }, 30 31 "load_balancer": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 }, 36 37 "lb_port": &schema.Schema{ 38 Type: schema.TypeInt, 39 Required: true, 40 ForceNew: true, 41 }, 42 43 "attribute": &schema.Schema{ 44 Type: schema.TypeSet, 45 Optional: true, 46 ForceNew: true, 47 Elem: &schema.Resource{ 48 Schema: map[string]*schema.Schema{ 49 "name": &schema.Schema{ 50 Type: schema.TypeString, 51 Required: true, 52 }, 53 54 "value": &schema.Schema{ 55 Type: schema.TypeString, 56 Required: true, 57 }, 58 }, 59 }, 60 Set: func(v interface{}) int { 61 var buf bytes.Buffer 62 m := v.(map[string]interface{}) 63 buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) 64 return hashcode.String(buf.String()) 65 }, 66 }, 67 }, 68 } 69 } 70 71 func resourceAwsLBSSLNegotiationPolicyCreate(d *schema.ResourceData, meta interface{}) error { 72 elbconn := meta.(*AWSClient).elbconn 73 74 // Provision the SSLNegotiationPolicy 75 lbspOpts := &elb.CreateLoadBalancerPolicyInput{ 76 LoadBalancerName: aws.String(d.Get("load_balancer").(string)), 77 PolicyName: aws.String(d.Get("name").(string)), 78 PolicyTypeName: aws.String("SSLNegotiationPolicyType"), 79 } 80 81 // Check for Policy Attributes 82 if v, ok := d.GetOk("attribute"); ok { 83 var err error 84 // Expand the "attribute" set to aws-sdk-go compat []*elb.PolicyAttribute 85 lbspOpts.PolicyAttributes, err = expandPolicyAttributes(v.(*schema.Set).List()) 86 if err != nil { 87 return err 88 } 89 } 90 91 log.Printf("[DEBUG] Load Balancer Policy opts: %#v", lbspOpts) 92 if _, err := elbconn.CreateLoadBalancerPolicy(lbspOpts); err != nil { 93 return fmt.Errorf("Error creating Load Balancer Policy: %s", err) 94 } 95 96 setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ 97 LoadBalancerName: aws.String(d.Get("load_balancer").(string)), 98 LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))), 99 PolicyNames: []*string{aws.String(d.Get("name").(string))}, 100 } 101 102 log.Printf("[DEBUG] SSL Negotiation create configuration: %#v", setLoadBalancerOpts) 103 if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil { 104 return fmt.Errorf("Error setting SSLNegotiationPolicy: %s", err) 105 } 106 107 d.SetId(fmt.Sprintf("%s:%d:%s", 108 *lbspOpts.LoadBalancerName, 109 *setLoadBalancerOpts.LoadBalancerPort, 110 *lbspOpts.PolicyName)) 111 return nil 112 } 113 114 func resourceAwsLBSSLNegotiationPolicyRead(d *schema.ResourceData, meta interface{}) error { 115 elbconn := meta.(*AWSClient).elbconn 116 117 lbName, lbPort, policyName := resourceAwsLBSSLNegotiationPolicyParseId(d.Id()) 118 119 request := &elb.DescribeLoadBalancerPoliciesInput{ 120 LoadBalancerName: aws.String(lbName), 121 PolicyNames: []*string{aws.String(policyName)}, 122 } 123 124 getResp, err := elbconn.DescribeLoadBalancerPolicies(request) 125 if err != nil { 126 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "PolicyNotFound" { 127 // The policy is gone. 128 d.SetId("") 129 return nil 130 } else if isLoadBalancerNotFound(err) { 131 // The ELB is gone now, so just remove it from the state 132 d.SetId("") 133 return nil 134 } 135 return fmt.Errorf("Error retrieving policy: %s", err) 136 } 137 138 if len(getResp.PolicyDescriptions) != 1 { 139 return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions) 140 } 141 142 // We can get away with this because there's only one policy returned 143 policyDesc := getResp.PolicyDescriptions[0] 144 attributes := flattenPolicyAttributes(policyDesc.PolicyAttributeDescriptions) 145 d.Set("attributes", attributes) 146 147 d.Set("name", policyName) 148 d.Set("load_balancer", lbName) 149 d.Set("lb_port", lbPort) 150 151 return nil 152 } 153 154 func resourceAwsLBSSLNegotiationPolicyDelete(d *schema.ResourceData, meta interface{}) error { 155 elbconn := meta.(*AWSClient).elbconn 156 157 lbName, _, policyName := resourceAwsLBSSLNegotiationPolicyParseId(d.Id()) 158 159 // Perversely, if we Set an empty list of PolicyNames, we detach the 160 // policies attached to a listener, which is required to delete the 161 // policy itself. 162 setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ 163 LoadBalancerName: aws.String(d.Get("load_balancer").(string)), 164 LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))), 165 PolicyNames: []*string{}, 166 } 167 168 if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil { 169 return fmt.Errorf("Error removing SSLNegotiationPolicy: %s", err) 170 } 171 172 request := &elb.DeleteLoadBalancerPolicyInput{ 173 LoadBalancerName: aws.String(lbName), 174 PolicyName: aws.String(policyName), 175 } 176 177 if _, err := elbconn.DeleteLoadBalancerPolicy(request); err != nil { 178 return fmt.Errorf("Error deleting SSL negotiation policy %s: %s", d.Id(), err) 179 } 180 return nil 181 } 182 183 // resourceAwsLBSSLNegotiationPolicyParseId takes an ID and parses it into 184 // it's constituent parts. You need three axes (LB name, policy name, and LB 185 // port) to create or identify an SSL negotiation policy in AWS's API. 186 func resourceAwsLBSSLNegotiationPolicyParseId(id string) (string, string, string) { 187 parts := strings.SplitN(id, ":", 3) 188 return parts[0], parts[1], parts[2] 189 }