github.com/bradfeehan/terraform@v0.7.0-rc3.0.20170529055808-34b45c5ad841/builtin/providers/aws/resource_aws_waf_xss_match_set.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     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/waf"
    10  	"github.com/hashicorp/errwrap"
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  )
    13  
    14  func resourceAwsWafXssMatchSet() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceAwsWafXssMatchSetCreate,
    17  		Read:   resourceAwsWafXssMatchSetRead,
    18  		Update: resourceAwsWafXssMatchSetUpdate,
    19  		Delete: resourceAwsWafXssMatchSetDelete,
    20  
    21  		Schema: map[string]*schema.Schema{
    22  			"name": &schema.Schema{
    23  				Type:     schema.TypeString,
    24  				Required: true,
    25  				ForceNew: true,
    26  			},
    27  			"xss_match_tuples": &schema.Schema{
    28  				Type:     schema.TypeSet,
    29  				Optional: true,
    30  				Elem: &schema.Resource{
    31  					Schema: map[string]*schema.Schema{
    32  						"field_to_match": {
    33  							Type:     schema.TypeSet,
    34  							Required: true,
    35  							MaxItems: 1,
    36  							Elem: &schema.Resource{
    37  								Schema: map[string]*schema.Schema{
    38  									"data": {
    39  										Type:     schema.TypeString,
    40  										Optional: true,
    41  									},
    42  									"type": {
    43  										Type:     schema.TypeString,
    44  										Required: true,
    45  									},
    46  								},
    47  							},
    48  						},
    49  						"text_transformation": &schema.Schema{
    50  							Type:     schema.TypeString,
    51  							Required: true,
    52  						},
    53  					},
    54  				},
    55  			},
    56  		},
    57  	}
    58  }
    59  
    60  func resourceAwsWafXssMatchSetCreate(d *schema.ResourceData, meta interface{}) error {
    61  	conn := meta.(*AWSClient).wafconn
    62  
    63  	log.Printf("[INFO] Creating XssMatchSet: %s", d.Get("name").(string))
    64  
    65  	wr := newWafRetryer(conn, "global")
    66  	out, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
    67  		params := &waf.CreateXssMatchSetInput{
    68  			ChangeToken: token,
    69  			Name:        aws.String(d.Get("name").(string)),
    70  		}
    71  
    72  		return conn.CreateXssMatchSet(params)
    73  	})
    74  	if err != nil {
    75  		return errwrap.Wrapf("[ERROR] Error creating XssMatchSet: {{err}}", err)
    76  	}
    77  	resp := out.(*waf.CreateXssMatchSetOutput)
    78  
    79  	d.SetId(*resp.XssMatchSet.XssMatchSetId)
    80  
    81  	return resourceAwsWafXssMatchSetUpdate(d, meta)
    82  }
    83  
    84  func resourceAwsWafXssMatchSetRead(d *schema.ResourceData, meta interface{}) error {
    85  	conn := meta.(*AWSClient).wafconn
    86  	log.Printf("[INFO] Reading XssMatchSet: %s", d.Get("name").(string))
    87  	params := &waf.GetXssMatchSetInput{
    88  		XssMatchSetId: aws.String(d.Id()),
    89  	}
    90  
    91  	resp, err := conn.GetXssMatchSet(params)
    92  	if err != nil {
    93  		if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "WAFNonexistentItemException" {
    94  			log.Printf("[WARN] WAF IPSet (%s) not found, error code (404)", d.Id())
    95  			d.SetId("")
    96  			return nil
    97  		}
    98  
    99  		return err
   100  	}
   101  
   102  	d.Set("name", resp.XssMatchSet.Name)
   103  	d.Set("xss_match_tuples", flattenWafXssMatchTuples(resp.XssMatchSet.XssMatchTuples))
   104  
   105  	return nil
   106  }
   107  
   108  func resourceAwsWafXssMatchSetUpdate(d *schema.ResourceData, meta interface{}) error {
   109  	conn := meta.(*AWSClient).wafconn
   110  
   111  	if d.HasChange("xss_match_tuples") {
   112  		o, n := d.GetChange("xss_match_tuples")
   113  		oldT, newT := o.(*schema.Set).List(), n.(*schema.Set).List()
   114  
   115  		err := updateXssMatchSetResource(d.Id(), oldT, newT, conn)
   116  		if err != nil {
   117  			return errwrap.Wrapf("[ERROR] Error updating XssMatchSet: {{err}}", err)
   118  		}
   119  	}
   120  
   121  	return resourceAwsWafXssMatchSetRead(d, meta)
   122  }
   123  
   124  func resourceAwsWafXssMatchSetDelete(d *schema.ResourceData, meta interface{}) error {
   125  	conn := meta.(*AWSClient).wafconn
   126  
   127  	oldTuples := d.Get("xss_match_tuples").(*schema.Set).List()
   128  	if len(oldTuples) > 0 {
   129  		noTuples := []interface{}{}
   130  		err := updateXssMatchSetResource(d.Id(), oldTuples, noTuples, conn)
   131  		if err != nil {
   132  			return fmt.Errorf("Error updating IPSetDescriptors: %s", err)
   133  		}
   134  	}
   135  
   136  	wr := newWafRetryer(conn, "global")
   137  	_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
   138  		req := &waf.DeleteXssMatchSetInput{
   139  			ChangeToken:   token,
   140  			XssMatchSetId: aws.String(d.Id()),
   141  		}
   142  
   143  		return conn.DeleteXssMatchSet(req)
   144  	})
   145  	if err != nil {
   146  		return errwrap.Wrapf("[ERROR] Error deleting XssMatchSet: {{err}}", err)
   147  	}
   148  
   149  	return nil
   150  }
   151  
   152  func updateXssMatchSetResource(id string, oldT, newT []interface{}, conn *waf.WAF) error {
   153  	wr := newWafRetryer(conn, "global")
   154  	_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
   155  		req := &waf.UpdateXssMatchSetInput{
   156  			ChangeToken:   token,
   157  			XssMatchSetId: aws.String(id),
   158  			Updates:       diffWafXssMatchSetTuples(oldT, newT),
   159  		}
   160  
   161  		log.Printf("[INFO] Updating XssMatchSet tuples: %s", req)
   162  		return conn.UpdateXssMatchSet(req)
   163  	})
   164  	if err != nil {
   165  		return errwrap.Wrapf("[ERROR] Error updating XssMatchSet: {{err}}", err)
   166  	}
   167  
   168  	return nil
   169  }
   170  
   171  func flattenWafXssMatchTuples(ts []*waf.XssMatchTuple) []interface{} {
   172  	out := make([]interface{}, len(ts), len(ts))
   173  	for i, t := range ts {
   174  		m := make(map[string]interface{})
   175  		m["field_to_match"] = flattenFieldToMatch(t.FieldToMatch)
   176  		m["text_transformation"] = *t.TextTransformation
   177  		out[i] = m
   178  	}
   179  	return out
   180  }
   181  
   182  func diffWafXssMatchSetTuples(oldT, newT []interface{}) []*waf.XssMatchSetUpdate {
   183  	updates := make([]*waf.XssMatchSetUpdate, 0)
   184  
   185  	for _, od := range oldT {
   186  		tuple := od.(map[string]interface{})
   187  
   188  		if idx, contains := sliceContainsMap(newT, tuple); contains {
   189  			newT = append(newT[:idx], newT[idx+1:]...)
   190  			continue
   191  		}
   192  
   193  		updates = append(updates, &waf.XssMatchSetUpdate{
   194  			Action: aws.String(waf.ChangeActionDelete),
   195  			XssMatchTuple: &waf.XssMatchTuple{
   196  				FieldToMatch:       expandFieldToMatch(tuple["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})),
   197  				TextTransformation: aws.String(tuple["text_transformation"].(string)),
   198  			},
   199  		})
   200  	}
   201  
   202  	for _, nd := range newT {
   203  		tuple := nd.(map[string]interface{})
   204  
   205  		updates = append(updates, &waf.XssMatchSetUpdate{
   206  			Action: aws.String(waf.ChangeActionInsert),
   207  			XssMatchTuple: &waf.XssMatchTuple{
   208  				FieldToMatch:       expandFieldToMatch(tuple["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})),
   209  				TextTransformation: aws.String(tuple["text_transformation"].(string)),
   210  			},
   211  		})
   212  	}
   213  	return updates
   214  }