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 }