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  }