github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/rabbitmq/resource_policy.go (about)

     1  package rabbitmq
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strings"
     7  
     8  	"github.com/michaelklishin/rabbit-hole"
     9  
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  )
    12  
    13  func resourcePolicy() *schema.Resource {
    14  	return &schema.Resource{
    15  		Create: CreatePolicy,
    16  		Update: UpdatePolicy,
    17  		Read:   ReadPolicy,
    18  		Delete: DeletePolicy,
    19  		Importer: &schema.ResourceImporter{
    20  			State: schema.ImportStatePassthrough,
    21  		},
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"name": &schema.Schema{
    25  				Type:     schema.TypeString,
    26  				Required: true,
    27  				ForceNew: true,
    28  			},
    29  
    30  			"vhost": &schema.Schema{
    31  				Type:     schema.TypeString,
    32  				Required: true,
    33  				ForceNew: true,
    34  			},
    35  
    36  			"policy": &schema.Schema{
    37  				Type:     schema.TypeList,
    38  				Required: true,
    39  				MaxItems: 1,
    40  				Elem: &schema.Resource{
    41  					Schema: map[string]*schema.Schema{
    42  						"pattern": &schema.Schema{
    43  							Type:     schema.TypeString,
    44  							Required: true,
    45  						},
    46  
    47  						"priority": &schema.Schema{
    48  							Type:     schema.TypeInt,
    49  							Required: true,
    50  						},
    51  
    52  						"apply_to": &schema.Schema{
    53  							Type:     schema.TypeString,
    54  							Required: true,
    55  						},
    56  
    57  						"definition": &schema.Schema{
    58  							Type:     schema.TypeMap,
    59  							Required: true,
    60  						},
    61  					},
    62  				},
    63  			},
    64  		},
    65  	}
    66  }
    67  
    68  func CreatePolicy(d *schema.ResourceData, meta interface{}) error {
    69  	rmqc := meta.(*rabbithole.Client)
    70  
    71  	name := d.Get("name").(string)
    72  	vhost := d.Get("vhost").(string)
    73  	policyList := d.Get("policy").([]interface{})
    74  
    75  	policyMap, ok := policyList[0].(map[string]interface{})
    76  	if !ok {
    77  		return fmt.Errorf("Unable to parse policy")
    78  	}
    79  
    80  	if err := putPolicy(rmqc, vhost, name, policyMap); err != nil {
    81  		return err
    82  	}
    83  
    84  	id := fmt.Sprintf("%s@%s", name, vhost)
    85  	d.SetId(id)
    86  
    87  	return ReadPolicy(d, meta)
    88  }
    89  
    90  func ReadPolicy(d *schema.ResourceData, meta interface{}) error {
    91  	rmqc := meta.(*rabbithole.Client)
    92  
    93  	policyId := strings.Split(d.Id(), "@")
    94  	if len(policyId) < 2 {
    95  		return fmt.Errorf("Unable to determine policy ID")
    96  	}
    97  
    98  	user := policyId[0]
    99  	vhost := policyId[1]
   100  
   101  	policy, err := rmqc.GetPolicy(vhost, user)
   102  	if err != nil {
   103  		return checkDeleted(d, err)
   104  	}
   105  
   106  	log.Printf("[DEBUG] RabbitMQ: Policy retrieved for %s: %#v", d.Id(), policy)
   107  
   108  	d.Set("name", policy.Name)
   109  	d.Set("vhost", policy.Vhost)
   110  
   111  	setPolicy := make([]map[string]interface{}, 1)
   112  	p := make(map[string]interface{})
   113  	p["pattern"] = policy.Pattern
   114  	p["priority"] = policy.Priority
   115  	p["apply_to"] = policy.ApplyTo
   116  
   117  	policyDefinition := make(map[string]interface{})
   118  	for key, value := range policy.Definition {
   119  		if v, ok := value.([]interface{}); ok {
   120  			var nodes []string
   121  			for _, node := range v {
   122  				if n, ok := node.(string); ok {
   123  					nodes = append(nodes, n)
   124  				}
   125  			}
   126  			value = strings.Join(nodes, ",")
   127  		}
   128  		policyDefinition[key] = value
   129  	}
   130  	p["definition"] = policyDefinition
   131  	setPolicy[0] = p
   132  
   133  	d.Set("policy", setPolicy)
   134  
   135  	return nil
   136  }
   137  
   138  func UpdatePolicy(d *schema.ResourceData, meta interface{}) error {
   139  	rmqc := meta.(*rabbithole.Client)
   140  
   141  	policyId := strings.Split(d.Id(), "@")
   142  	if len(policyId) < 2 {
   143  		return fmt.Errorf("Unable to determine policy ID")
   144  	}
   145  
   146  	user := policyId[0]
   147  	vhost := policyId[1]
   148  
   149  	if d.HasChange("policy") {
   150  		_, newPolicy := d.GetChange("policy")
   151  
   152  		policyList := newPolicy.([]interface{})
   153  		policyMap, ok := policyList[0].(map[string]interface{})
   154  		if !ok {
   155  			return fmt.Errorf("Unable to parse policy")
   156  		}
   157  
   158  		if err := putPolicy(rmqc, user, vhost, policyMap); err != nil {
   159  			return err
   160  		}
   161  	}
   162  
   163  	return ReadPolicy(d, meta)
   164  }
   165  
   166  func DeletePolicy(d *schema.ResourceData, meta interface{}) error {
   167  	rmqc := meta.(*rabbithole.Client)
   168  
   169  	policyId := strings.Split(d.Id(), "@")
   170  	if len(policyId) < 2 {
   171  		return fmt.Errorf("Unable to determine policy ID")
   172  	}
   173  
   174  	user := policyId[0]
   175  	vhost := policyId[1]
   176  
   177  	log.Printf("[DEBUG] RabbitMQ: Attempting to delete policy for %s", d.Id())
   178  
   179  	resp, err := rmqc.DeletePolicy(vhost, user)
   180  	log.Printf("[DEBUG] RabbitMQ: Policy delete response: %#v", resp)
   181  	if err != nil {
   182  		return err
   183  	}
   184  
   185  	if resp.StatusCode == 404 {
   186  		// the policy was automatically deleted
   187  		return nil
   188  	}
   189  
   190  	if resp.StatusCode >= 400 {
   191  		return fmt.Errorf("Error deleting RabbitMQ policy: %s", resp.Status)
   192  	}
   193  
   194  	return nil
   195  }
   196  
   197  func putPolicy(rmqc *rabbithole.Client, vhost string, name string, policyMap map[string]interface{}) error {
   198  	policy := rabbithole.Policy{}
   199  	policy.Vhost = vhost
   200  	policy.Name = name
   201  
   202  	if v, ok := policyMap["pattern"].(string); ok {
   203  		policy.Pattern = v
   204  	}
   205  
   206  	if v, ok := policyMap["priority"].(int); ok {
   207  		policy.Priority = v
   208  	}
   209  
   210  	if v, ok := policyMap["apply_to"].(string); ok {
   211  		policy.ApplyTo = v
   212  	}
   213  
   214  	if v, ok := policyMap["definition"].(map[string]interface{}); ok {
   215  		// special case for ha-mode = nodes
   216  		if x, ok := v["ha-mode"]; ok && x == "nodes" {
   217  			var nodes rabbithole.NodeNames
   218  			nodes = strings.Split(v["ha-params"].(string), ",")
   219  			v["ha-params"] = nodes
   220  		}
   221  		policyDefinition := rabbithole.PolicyDefinition{}
   222  		policyDefinition = v
   223  		policy.Definition = policyDefinition
   224  	}
   225  
   226  	log.Printf("[DEBUG] RabbitMQ: Attempting to declare policy for %s@%s: %#v", name, vhost, policy)
   227  
   228  	resp, err := rmqc.PutPolicy(vhost, name, policy)
   229  	log.Printf("[DEBUG] RabbitMQ: Policy declare response: %#v", resp)
   230  	if err != nil {
   231  		return err
   232  	}
   233  
   234  	if resp.StatusCode >= 400 {
   235  		return fmt.Errorf("Error declaring RabbitMQ policy: %s", resp.Status)
   236  	}
   237  
   238  	return nil
   239  }