github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/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  }