github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_waf_ipset.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/terraform/helper/schema" 11 ) 12 13 func resourceAwsWafIPSet() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourceAwsWafIPSetCreate, 16 Read: resourceAwsWafIPSetRead, 17 Update: resourceAwsWafIPSetUpdate, 18 Delete: resourceAwsWafIPSetDelete, 19 20 Schema: map[string]*schema.Schema{ 21 "name": &schema.Schema{ 22 Type: schema.TypeString, 23 Required: true, 24 ForceNew: true, 25 }, 26 "ip_set_descriptors": &schema.Schema{ 27 Type: schema.TypeSet, 28 Optional: true, 29 Elem: &schema.Resource{ 30 Schema: map[string]*schema.Schema{ 31 "type": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 }, 35 "value": &schema.Schema{ 36 Type: schema.TypeString, 37 Required: true, 38 }, 39 }, 40 }, 41 }, 42 }, 43 } 44 } 45 46 func resourceAwsWafIPSetCreate(d *schema.ResourceData, meta interface{}) error { 47 conn := meta.(*AWSClient).wafconn 48 49 wr := newWafRetryer(conn, "global") 50 out, err := wr.RetryWithToken(func(token *string) (interface{}, error) { 51 params := &waf.CreateIPSetInput{ 52 ChangeToken: token, 53 Name: aws.String(d.Get("name").(string)), 54 } 55 return conn.CreateIPSet(params) 56 }) 57 if err != nil { 58 return err 59 } 60 resp := out.(*waf.CreateIPSetOutput) 61 d.SetId(*resp.IPSet.IPSetId) 62 return resourceAwsWafIPSetUpdate(d, meta) 63 } 64 65 func resourceAwsWafIPSetRead(d *schema.ResourceData, meta interface{}) error { 66 conn := meta.(*AWSClient).wafconn 67 68 params := &waf.GetIPSetInput{ 69 IPSetId: aws.String(d.Id()), 70 } 71 72 resp, err := conn.GetIPSet(params) 73 if err != nil { 74 if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "WAFNonexistentItemException" { 75 log.Printf("[WARN] WAF IPSet (%s) not found, error code (404)", d.Id()) 76 d.SetId("") 77 return nil 78 } 79 80 return err 81 } 82 83 var descriptors []map[string]interface{} 84 85 for _, descriptor := range resp.IPSet.IPSetDescriptors { 86 d := map[string]interface{}{ 87 "type": *descriptor.Type, 88 "value": *descriptor.Value, 89 } 90 descriptors = append(descriptors, d) 91 } 92 93 d.Set("ip_set_descriptors", descriptors) 94 95 d.Set("name", resp.IPSet.Name) 96 97 return nil 98 } 99 100 func resourceAwsWafIPSetUpdate(d *schema.ResourceData, meta interface{}) error { 101 conn := meta.(*AWSClient).wafconn 102 103 if d.HasChange("ip_set_descriptors") { 104 o, n := d.GetChange("ip_set_descriptors") 105 oldD, newD := o.(*schema.Set).List(), n.(*schema.Set).List() 106 107 err := updateWafIpSetDescriptors(d.Id(), oldD, newD, conn) 108 if err != nil { 109 return fmt.Errorf("Error Updating WAF IPSet: %s", err) 110 } 111 } 112 113 return resourceAwsWafIPSetRead(d, meta) 114 } 115 116 func resourceAwsWafIPSetDelete(d *schema.ResourceData, meta interface{}) error { 117 conn := meta.(*AWSClient).wafconn 118 119 oldDescriptors := d.Get("ip_set_descriptors").(*schema.Set).List() 120 121 if len(oldDescriptors) > 0 { 122 noDescriptors := []interface{}{} 123 err := updateWafIpSetDescriptors(d.Id(), oldDescriptors, noDescriptors, conn) 124 if err != nil { 125 return fmt.Errorf("Error updating IPSetDescriptors: %s", err) 126 } 127 } 128 129 wr := newWafRetryer(conn, "global") 130 _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { 131 req := &waf.DeleteIPSetInput{ 132 ChangeToken: token, 133 IPSetId: aws.String(d.Id()), 134 } 135 log.Printf("[INFO] Deleting WAF IPSet") 136 return conn.DeleteIPSet(req) 137 }) 138 if err != nil { 139 return fmt.Errorf("Error Deleting WAF IPSet: %s", err) 140 } 141 142 return nil 143 } 144 145 func updateWafIpSetDescriptors(id string, oldD, newD []interface{}, conn *waf.WAF) error { 146 wr := newWafRetryer(conn, "global") 147 _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { 148 req := &waf.UpdateIPSetInput{ 149 ChangeToken: token, 150 IPSetId: aws.String(id), 151 Updates: diffWafIpSetDescriptors(oldD, newD), 152 } 153 log.Printf("[INFO] Updating IPSet descriptors: %s", req) 154 return conn.UpdateIPSet(req) 155 }) 156 if err != nil { 157 return fmt.Errorf("Error Updating WAF IPSet: %s", err) 158 } 159 160 return nil 161 } 162 163 func diffWafIpSetDescriptors(oldD, newD []interface{}) []*waf.IPSetUpdate { 164 updates := make([]*waf.IPSetUpdate, 0) 165 166 for _, od := range oldD { 167 descriptor := od.(map[string]interface{}) 168 169 if idx, contains := sliceContainsMap(newD, descriptor); contains { 170 newD = append(newD[:idx], newD[idx+1:]...) 171 continue 172 } 173 174 updates = append(updates, &waf.IPSetUpdate{ 175 Action: aws.String(waf.ChangeActionDelete), 176 IPSetDescriptor: &waf.IPSetDescriptor{ 177 Type: aws.String(descriptor["type"].(string)), 178 Value: aws.String(descriptor["value"].(string)), 179 }, 180 }) 181 } 182 183 for _, nd := range newD { 184 descriptor := nd.(map[string]interface{}) 185 186 updates = append(updates, &waf.IPSetUpdate{ 187 Action: aws.String(waf.ChangeActionInsert), 188 IPSetDescriptor: &waf.IPSetDescriptor{ 189 Type: aws.String(descriptor["type"].(string)), 190 Value: aws.String(descriptor["value"].(string)), 191 }, 192 }) 193 } 194 return updates 195 }