github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_load_balancer_policy.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/aws/awserr" 9 "github.com/aws/aws-sdk-go/service/elb" 10 "github.com/hashicorp/terraform/helper/schema" 11 ) 12 13 func resourceAwsLoadBalancerPolicy() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourceAwsLoadBalancerPolicyCreate, 16 Read: resourceAwsLoadBalancerPolicyRead, 17 Update: resourceAwsLoadBalancerPolicyUpdate, 18 Delete: resourceAwsLoadBalancerPolicyDelete, 19 20 Schema: map[string]*schema.Schema{ 21 "load_balancer_name": &schema.Schema{ 22 Type: schema.TypeString, 23 Required: true, 24 ForceNew: true, 25 }, 26 27 "policy_name": &schema.Schema{ 28 Type: schema.TypeString, 29 Required: true, 30 ForceNew: true, 31 }, 32 33 "policy_type_name": &schema.Schema{ 34 Type: schema.TypeString, 35 Required: true, 36 ForceNew: true, 37 }, 38 39 "policy_attribute": &schema.Schema{ 40 Type: schema.TypeSet, 41 Optional: true, 42 Elem: &schema.Resource{ 43 Schema: map[string]*schema.Schema{ 44 "name": &schema.Schema{ 45 Type: schema.TypeString, 46 Optional: true, 47 }, 48 49 "value": &schema.Schema{ 50 Type: schema.TypeString, 51 Optional: true, 52 }, 53 }, 54 }, 55 }, 56 }, 57 } 58 } 59 60 func resourceAwsLoadBalancerPolicyCreate(d *schema.ResourceData, meta interface{}) error { 61 elbconn := meta.(*AWSClient).elbconn 62 63 attributes := []*elb.PolicyAttribute{} 64 if attributedata, ok := d.GetOk("policy_attribute"); ok { 65 attributeSet := attributedata.(*schema.Set).List() 66 for _, attribute := range attributeSet { 67 data := attribute.(map[string]interface{}) 68 attributes = append(attributes, &elb.PolicyAttribute{ 69 AttributeName: aws.String(data["name"].(string)), 70 AttributeValue: aws.String(data["value"].(string)), 71 }) 72 } 73 } 74 75 lbspOpts := &elb.CreateLoadBalancerPolicyInput{ 76 LoadBalancerName: aws.String(d.Get("load_balancer_name").(string)), 77 PolicyName: aws.String(d.Get("policy_name").(string)), 78 PolicyTypeName: aws.String(d.Get("policy_type_name").(string)), 79 PolicyAttributes: attributes, 80 } 81 82 if _, err := elbconn.CreateLoadBalancerPolicy(lbspOpts); err != nil { 83 return fmt.Errorf("Error creating LoadBalancerPolicy: %s", err) 84 } 85 86 d.SetId(fmt.Sprintf("%s:%s", 87 *lbspOpts.LoadBalancerName, 88 *lbspOpts.PolicyName)) 89 return resourceAwsLoadBalancerPolicyRead(d, meta) 90 } 91 92 func resourceAwsLoadBalancerPolicyRead(d *schema.ResourceData, meta interface{}) error { 93 elbconn := meta.(*AWSClient).elbconn 94 95 loadBalancerName, policyName := resourceAwsLoadBalancerPolicyParseId(d.Id()) 96 97 request := &elb.DescribeLoadBalancerPoliciesInput{ 98 LoadBalancerName: aws.String(loadBalancerName), 99 PolicyNames: []*string{aws.String(policyName)}, 100 } 101 102 getResp, err := elbconn.DescribeLoadBalancerPolicies(request) 103 if err != nil { 104 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "PolicyNotFound" { 105 d.SetId("") 106 return nil 107 } 108 return fmt.Errorf("Error retrieving policy: %s", err) 109 } 110 111 if len(getResp.PolicyDescriptions) != 1 { 112 return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions) 113 } 114 115 policyDesc := getResp.PolicyDescriptions[0] 116 policyTypeName := policyDesc.PolicyTypeName 117 policyAttributes := policyDesc.PolicyAttributeDescriptions 118 119 attributes := []map[string]string{} 120 for _, a := range policyAttributes { 121 pair := make(map[string]string) 122 pair["name"] = *a.AttributeName 123 pair["value"] = *a.AttributeValue 124 if (*policyTypeName == "SSLNegotiationPolicyType") && (*a.AttributeValue == "false") { 125 continue 126 } 127 attributes = append(attributes, pair) 128 } 129 130 d.Set("policy_name", policyName) 131 d.Set("policy_type_name", policyTypeName) 132 d.Set("load_balancer_name", loadBalancerName) 133 d.Set("policy_attribute", attributes) 134 135 return nil 136 } 137 138 func resourceAwsLoadBalancerPolicyUpdate(d *schema.ResourceData, meta interface{}) error { 139 elbconn := meta.(*AWSClient).elbconn 140 reassignments := Reassignment{} 141 142 loadBalancerName, policyName := resourceAwsLoadBalancerPolicyParseId(d.Id()) 143 144 assigned, err := resourceAwsLoadBalancerPolicyAssigned(policyName, loadBalancerName, elbconn) 145 if err != nil { 146 return fmt.Errorf("Error determining assignment status of Load Balancer Policy %s: %s", policyName, err) 147 } 148 149 if assigned { 150 reassignments, err = resourceAwsLoadBalancerPolicyUnassign(policyName, loadBalancerName, elbconn) 151 if err != nil { 152 return fmt.Errorf("Error unassigning Load Balancer Policy %s: %s", policyName, err) 153 } 154 } 155 156 request := &elb.DeleteLoadBalancerPolicyInput{ 157 LoadBalancerName: aws.String(loadBalancerName), 158 PolicyName: aws.String(policyName), 159 } 160 161 if _, err := elbconn.DeleteLoadBalancerPolicy(request); err != nil { 162 return fmt.Errorf("Error deleting Load Balancer Policy %s: %s", d.Id(), err) 163 } 164 165 err = resourceAwsLoadBalancerPolicyCreate(d, meta) 166 167 for _, listenerAssignment := range reassignments.listenerPolicies { 168 if _, err := elbconn.SetLoadBalancerPoliciesOfListener(listenerAssignment); err != nil { 169 return fmt.Errorf("Error setting LoadBalancerPoliciesOfListener: %s", err) 170 } 171 } 172 173 for _, backendServerAssignment := range reassignments.backendServerPolicies { 174 if _, err := elbconn.SetLoadBalancerPoliciesForBackendServer(backendServerAssignment); err != nil { 175 return fmt.Errorf("Error setting LoadBalancerPoliciesForBackendServer: %s", err) 176 } 177 } 178 179 return resourceAwsLoadBalancerPolicyRead(d, meta) 180 } 181 182 func resourceAwsLoadBalancerPolicyDelete(d *schema.ResourceData, meta interface{}) error { 183 elbconn := meta.(*AWSClient).elbconn 184 185 loadBalancerName, policyName := resourceAwsLoadBalancerPolicyParseId(d.Id()) 186 187 assigned, err := resourceAwsLoadBalancerPolicyAssigned(policyName, loadBalancerName, elbconn) 188 if err != nil { 189 return fmt.Errorf("Error determining assignment status of Load Balancer Policy %s: %s", policyName, err) 190 } 191 192 if assigned { 193 _, err := resourceAwsLoadBalancerPolicyUnassign(policyName, loadBalancerName, elbconn) 194 if err != nil { 195 return fmt.Errorf("Error unassigning Load Balancer Policy %s: %s", policyName, err) 196 } 197 } 198 199 request := &elb.DeleteLoadBalancerPolicyInput{ 200 LoadBalancerName: aws.String(loadBalancerName), 201 PolicyName: aws.String(policyName), 202 } 203 204 if _, err := elbconn.DeleteLoadBalancerPolicy(request); err != nil { 205 return fmt.Errorf("Error deleting Load Balancer Policy %s: %s", d.Id(), err) 206 } 207 208 d.SetId("") 209 return nil 210 } 211 212 func resourceAwsLoadBalancerPolicyParseId(id string) (string, string) { 213 parts := strings.SplitN(id, ":", 2) 214 return parts[0], parts[1] 215 } 216 217 func resourceAwsLoadBalancerPolicyAssigned(policyName, loadBalancerName string, elbconn *elb.ELB) (bool, error) { 218 describeElbOpts := &elb.DescribeLoadBalancersInput{ 219 LoadBalancerNames: []*string{aws.String(loadBalancerName)}, 220 } 221 222 describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts) 223 224 if err != nil { 225 if ec2err, ok := err.(awserr.Error); ok { 226 if ec2err.Code() == "LoadBalancerNotFound" { 227 return false, nil 228 } 229 } 230 return false, fmt.Errorf("Error retrieving ELB description: %s", err) 231 } 232 233 if len(describeResp.LoadBalancerDescriptions) != 1 { 234 return false, fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancerDescriptions) 235 } 236 237 lb := describeResp.LoadBalancerDescriptions[0] 238 assigned := false 239 for _, backendServer := range lb.BackendServerDescriptions { 240 for _, name := range backendServer.PolicyNames { 241 if policyName == *name { 242 assigned = true 243 break 244 } 245 } 246 } 247 248 for _, listener := range lb.ListenerDescriptions { 249 for _, name := range listener.PolicyNames { 250 if policyName == *name { 251 assigned = true 252 break 253 } 254 } 255 } 256 257 return assigned, nil 258 } 259 260 type Reassignment struct { 261 backendServerPolicies []*elb.SetLoadBalancerPoliciesForBackendServerInput 262 listenerPolicies []*elb.SetLoadBalancerPoliciesOfListenerInput 263 } 264 265 func resourceAwsLoadBalancerPolicyUnassign(policyName, loadBalancerName string, elbconn *elb.ELB) (Reassignment, error) { 266 reassignments := Reassignment{} 267 268 describeElbOpts := &elb.DescribeLoadBalancersInput{ 269 LoadBalancerNames: []*string{aws.String(loadBalancerName)}, 270 } 271 272 describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts) 273 274 if err != nil { 275 if ec2err, ok := err.(awserr.Error); ok { 276 if ec2err.Code() == "LoadBalancerNotFound" { 277 return reassignments, nil 278 } 279 } 280 return reassignments, fmt.Errorf("Error retrieving ELB description: %s", err) 281 } 282 283 if len(describeResp.LoadBalancerDescriptions) != 1 { 284 return reassignments, fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancerDescriptions) 285 } 286 287 lb := describeResp.LoadBalancerDescriptions[0] 288 289 for _, backendServer := range lb.BackendServerDescriptions { 290 policies := []*string{} 291 292 for _, name := range backendServer.PolicyNames { 293 if policyName != *name { 294 policies = append(policies, name) 295 } 296 } 297 298 if len(backendServer.PolicyNames) != len(policies) { 299 setOpts := &elb.SetLoadBalancerPoliciesForBackendServerInput{ 300 LoadBalancerName: aws.String(loadBalancerName), 301 InstancePort: aws.Int64(*backendServer.InstancePort), 302 PolicyNames: policies, 303 } 304 305 reassignOpts := &elb.SetLoadBalancerPoliciesForBackendServerInput{ 306 LoadBalancerName: aws.String(loadBalancerName), 307 InstancePort: aws.Int64(*backendServer.InstancePort), 308 PolicyNames: backendServer.PolicyNames, 309 } 310 311 reassignments.backendServerPolicies = append(reassignments.backendServerPolicies, reassignOpts) 312 313 _, err = elbconn.SetLoadBalancerPoliciesForBackendServer(setOpts) 314 if err != nil { 315 return reassignments, fmt.Errorf("Error Setting Load Balancer Policies for Backend Server: %s", err) 316 } 317 } 318 } 319 320 for _, listener := range lb.ListenerDescriptions { 321 policies := []*string{} 322 323 for _, name := range listener.PolicyNames { 324 if policyName != *name { 325 policies = append(policies, name) 326 } 327 } 328 329 if len(listener.PolicyNames) != len(policies) { 330 setOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ 331 LoadBalancerName: aws.String(loadBalancerName), 332 LoadBalancerPort: aws.Int64(*listener.Listener.LoadBalancerPort), 333 PolicyNames: policies, 334 } 335 336 reassignOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{ 337 LoadBalancerName: aws.String(loadBalancerName), 338 LoadBalancerPort: aws.Int64(*listener.Listener.LoadBalancerPort), 339 PolicyNames: listener.PolicyNames, 340 } 341 342 reassignments.listenerPolicies = append(reassignments.listenerPolicies, reassignOpts) 343 344 _, err = elbconn.SetLoadBalancerPoliciesOfListener(setOpts) 345 if err != nil { 346 return reassignments, fmt.Errorf("Error Setting Load Balancer Policies of Listener: %s", err) 347 } 348 } 349 } 350 351 return reassignments, nil 352 }