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  }