github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/builtin/providers/aws/resource_aws_alb_listener_rule.go (about)

     1  package aws
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"log"
     7  	"strconv"
     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/elbv2"
    12  	"github.com/hashicorp/errwrap"
    13  	"github.com/hashicorp/terraform/helper/schema"
    14  )
    15  
    16  func resourceAwsAlbListenerRule() *schema.Resource {
    17  	return &schema.Resource{
    18  		Create: resourceAwsAlbListenerRuleCreate,
    19  		Read:   resourceAwsAlbListenerRuleRead,
    20  		Update: resourceAwsAlbListenerRuleUpdate,
    21  		Delete: resourceAwsAlbListenerRuleDelete,
    22  		Importer: &schema.ResourceImporter{
    23  			State: schema.ImportStatePassthrough,
    24  		},
    25  
    26  		Schema: map[string]*schema.Schema{
    27  			"arn": {
    28  				Type:     schema.TypeString,
    29  				Computed: true,
    30  			},
    31  			"listener_arn": {
    32  				Type:     schema.TypeString,
    33  				Required: true,
    34  			},
    35  			"priority": {
    36  				Type:         schema.TypeInt,
    37  				Required:     true,
    38  				ValidateFunc: validateAwsAlbListenerRulePriority,
    39  			},
    40  			"action": {
    41  				Type:     schema.TypeList,
    42  				Required: true,
    43  				Elem: &schema.Resource{
    44  					Schema: map[string]*schema.Schema{
    45  						"target_group_arn": {
    46  							Type:     schema.TypeString,
    47  							Required: true,
    48  						},
    49  						"type": {
    50  							Type:         schema.TypeString,
    51  							Required:     true,
    52  							ValidateFunc: validateAwsAlbListenerActionType,
    53  						},
    54  					},
    55  				},
    56  			},
    57  			"condition": {
    58  				Type:     schema.TypeList,
    59  				Required: true,
    60  				Elem: &schema.Resource{
    61  					Schema: map[string]*schema.Schema{
    62  						"field": {
    63  							Type:         schema.TypeString,
    64  							Optional:     true,
    65  							ValidateFunc: validateAwsListenerRuleField,
    66  						},
    67  						"values": {
    68  							Type:     schema.TypeList,
    69  							Elem:     &schema.Schema{Type: schema.TypeString},
    70  							Optional: true,
    71  						},
    72  					},
    73  				},
    74  			},
    75  		},
    76  	}
    77  }
    78  
    79  func resourceAwsAlbListenerRuleCreate(d *schema.ResourceData, meta interface{}) error {
    80  	elbconn := meta.(*AWSClient).elbv2conn
    81  
    82  	params := &elbv2.CreateRuleInput{
    83  		ListenerArn: aws.String(d.Get("listener_arn").(string)),
    84  		Priority:    aws.Int64(int64(d.Get("priority").(int))),
    85  	}
    86  
    87  	actions := d.Get("action").([]interface{})
    88  	params.Actions = make([]*elbv2.Action, len(actions))
    89  	for i, action := range actions {
    90  		actionMap := action.(map[string]interface{})
    91  		params.Actions[i] = &elbv2.Action{
    92  			TargetGroupArn: aws.String(actionMap["target_group_arn"].(string)),
    93  			Type:           aws.String(actionMap["type"].(string)),
    94  		}
    95  	}
    96  
    97  	conditions := d.Get("condition").([]interface{})
    98  	params.Conditions = make([]*elbv2.RuleCondition, len(conditions))
    99  	for i, condition := range conditions {
   100  		conditionMap := condition.(map[string]interface{})
   101  		values := conditionMap["values"].([]interface{})
   102  		params.Conditions[i] = &elbv2.RuleCondition{
   103  			Field:  aws.String(conditionMap["field"].(string)),
   104  			Values: make([]*string, len(values)),
   105  		}
   106  		for j, value := range values {
   107  			params.Conditions[i].Values[j] = aws.String(value.(string))
   108  		}
   109  	}
   110  
   111  	resp, err := elbconn.CreateRule(params)
   112  	if err != nil {
   113  		return errwrap.Wrapf("Error creating ALB Listener Rule: {{err}}", err)
   114  	}
   115  
   116  	if len(resp.Rules) == 0 {
   117  		return errors.New("Error creating ALB Listener Rule: no rules returned in response")
   118  	}
   119  
   120  	d.SetId(*resp.Rules[0].RuleArn)
   121  
   122  	return resourceAwsAlbListenerRuleRead(d, meta)
   123  }
   124  
   125  func resourceAwsAlbListenerRuleRead(d *schema.ResourceData, meta interface{}) error {
   126  	elbconn := meta.(*AWSClient).elbv2conn
   127  
   128  	resp, err := elbconn.DescribeRules(&elbv2.DescribeRulesInput{
   129  		RuleArns: []*string{aws.String(d.Id())},
   130  	})
   131  	if err != nil {
   132  		if isRuleNotFound(err) {
   133  			log.Printf("[WARN] DescribeRules - removing %s from state", d.Id())
   134  			d.SetId("")
   135  			return nil
   136  		}
   137  		return errwrap.Wrapf(fmt.Sprintf("Error retrieving Rules for listener %s: {{err}}", d.Id()), err)
   138  	}
   139  
   140  	if len(resp.Rules) != 1 {
   141  		return fmt.Errorf("Error retrieving Rule %q", d.Id())
   142  	}
   143  
   144  	rule := resp.Rules[0]
   145  
   146  	d.Set("arn", rule.RuleArn)
   147  	if priority, err := strconv.Atoi(*rule.Priority); err != nil {
   148  		return errwrap.Wrapf("Cannot convert rule priority %q to int: {{err}}", err)
   149  	} else {
   150  		d.Set("priority", priority)
   151  	}
   152  
   153  	actions := make([]interface{}, len(rule.Actions))
   154  	for i, action := range rule.Actions {
   155  		actionMap := make(map[string]interface{})
   156  		actionMap["target_group_arn"] = *action.TargetGroupArn
   157  		actionMap["type"] = *action.Type
   158  		actions[i] = actionMap
   159  	}
   160  	d.Set("action", actions)
   161  
   162  	conditions := make([]interface{}, len(rule.Conditions))
   163  	for i, condition := range rule.Conditions {
   164  		conditionMap := make(map[string]interface{})
   165  		conditionMap["field"] = *condition.Field
   166  		conditionValues := make([]string, len(condition.Values))
   167  		for k, value := range condition.Values {
   168  			conditionValues[k] = *value
   169  		}
   170  		conditionMap["values"] = conditionValues
   171  		conditions[i] = conditionMap
   172  	}
   173  	d.Set("condition", conditions)
   174  
   175  	return nil
   176  }
   177  
   178  func resourceAwsAlbListenerRuleUpdate(d *schema.ResourceData, meta interface{}) error {
   179  	elbconn := meta.(*AWSClient).elbv2conn
   180  
   181  	params := &elbv2.ModifyRuleInput{
   182  		RuleArn: aws.String(d.Id()),
   183  	}
   184  
   185  	actions := d.Get("action").([]interface{})
   186  	params.Actions = make([]*elbv2.Action, len(actions))
   187  	for i, action := range actions {
   188  		actionMap := action.(map[string]interface{})
   189  		params.Actions[i] = &elbv2.Action{
   190  			TargetGroupArn: aws.String(actionMap["target_group_arn"].(string)),
   191  			Type:           aws.String(actionMap["type"].(string)),
   192  		}
   193  	}
   194  
   195  	conditions := d.Get("condition").([]interface{})
   196  	params.Conditions = make([]*elbv2.RuleCondition, len(conditions))
   197  	for i, condition := range conditions {
   198  		conditionMap := condition.(map[string]interface{})
   199  		values := conditionMap["values"].([]interface{})
   200  		params.Conditions[i] = &elbv2.RuleCondition{
   201  			Field:  aws.String(conditionMap["field"].(string)),
   202  			Values: make([]*string, len(values)),
   203  		}
   204  		for j, value := range values {
   205  			params.Conditions[i].Values[j] = aws.String(value.(string))
   206  		}
   207  	}
   208  
   209  	resp, err := elbconn.ModifyRule(params)
   210  	if err != nil {
   211  		return errwrap.Wrapf("Error modifying ALB Listener Rule: {{err}}", err)
   212  	}
   213  
   214  	if len(resp.Rules) == 0 {
   215  		return errors.New("Error modifying creating ALB Listener Rule: no rules returned in response")
   216  	}
   217  
   218  	return resourceAwsAlbListenerRuleRead(d, meta)
   219  }
   220  
   221  func resourceAwsAlbListenerRuleDelete(d *schema.ResourceData, meta interface{}) error {
   222  	elbconn := meta.(*AWSClient).elbv2conn
   223  
   224  	_, err := elbconn.DeleteRule(&elbv2.DeleteRuleInput{
   225  		RuleArn: aws.String(d.Id()),
   226  	})
   227  	if err != nil && !isRuleNotFound(err) {
   228  		return errwrap.Wrapf("Error deleting ALB Listener Rule: {{err}}", err)
   229  	}
   230  	return nil
   231  }
   232  
   233  func validateAwsAlbListenerRulePriority(v interface{}, k string) (ws []string, errors []error) {
   234  	value := v.(int)
   235  	if value < 1 || value > 99999 {
   236  		errors = append(errors, fmt.Errorf("%q must be in the range 1-99999", k))
   237  	}
   238  	return
   239  }
   240  
   241  func validateAwsListenerRuleField(v interface{}, k string) (ws []string, errors []error) {
   242  	value := v.(string)
   243  	if len(value) > 64 {
   244  		errors = append(errors, fmt.Errorf("%q must be a maximum of 64 characters", k))
   245  	}
   246  	return
   247  }
   248  
   249  func isRuleNotFound(err error) bool {
   250  	elberr, ok := err.(awserr.Error)
   251  	return ok && elberr.Code() == "RuleNotFound"
   252  }