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 }