use ForceNew on just about all catalog entry attributes; struggle in the hell of 'diffs mismatch'

This commit is contained in:
Max Englander 2015-10-29 05:04:25 -04:00
parent 7b9ec59258
commit 8d6b71e2ae
1 changed files with 58 additions and 14 deletions

View File

@ -3,6 +3,8 @@ package consul
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"sort"
"strings"
consulapi "github.com/hashicorp/consul/api" consulapi "github.com/hashicorp/consul/api"
"github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/hashcode"
@ -20,6 +22,7 @@ func resourceConsulCatalogEntry() *schema.Resource {
"address": &schema.Schema{ "address": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true,
}, },
"datacenter": &schema.Schema{ "datacenter": &schema.Schema{
@ -32,37 +35,44 @@ func resourceConsulCatalogEntry() *schema.Resource {
"node": &schema.Schema{ "node": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true,
}, },
"service": &schema.Schema{ "service": &schema.Schema{
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
ForceNew: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"address": &schema.Schema{ "address": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
ForceNew: true,
}, },
"id": &schema.Schema{ "id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true,
}, },
"name": &schema.Schema{ "name": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true,
}, },
"port": &schema.Schema{ "port": &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
ForceNew: true,
}, },
"tags": &schema.Schema{ "tags": &schema.Schema{
Type: schema.TypeList, Type: schema.TypeList,
Optional: true, Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
@ -82,6 +92,21 @@ func resourceConsulCatalogEntryServicesHash(v interface{}) int {
var buf bytes.Buffer var buf bytes.Buffer
m := v.(map[string]interface{}) m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%s-", m["id"].(string))) buf.WriteString(fmt.Sprintf("%s-", m["id"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["address"].(string)))
buf.WriteString(fmt.Sprintf("%d-", m["port"].(int)))
if v, ok := m["tags"]; ok {
vs := v.([]interface{})
s := make([]string, len(vs))
for i, raw := range vs {
s[i] = raw.(string)
}
sort.Strings(s)
for _, v := range s {
buf.WriteString(fmt.Sprintf("%s-", v))
}
}
return hashcode.String(buf.String()) return hashcode.String(buf.String())
} }
@ -110,42 +135,50 @@ func resourceConsulCatalogEntryCreate(d *schema.ResourceData, meta interface{})
address := d.Get("address").(string) address := d.Get("address").(string)
node := d.Get("node").(string) node := d.Get("node").(string)
if services, ok := d.GetOk("service"); ok { var serviceIDs []string
for _, rawService := range services.(*schema.Set).List() { if service, ok := d.GetOk("service"); ok {
serviceList := service.(*schema.Set).List()
serviceIDs = make([]string, len(serviceList))
for i, rawService := range serviceList {
serviceData := rawService.(map[string]interface{}) serviceData := rawService.(map[string]interface{})
rawTags := serviceData["tags"].([]interface{}) serviceID := serviceData["id"].(string)
tags := make([]string, len(rawTags)) serviceIDs[i] = serviceID
for i, v := range rawTags {
tags[i] = v.(string) var tags []string
if v := serviceData["tags"].([]interface{}); len(v) > 0 {
tags = make([]string, len(v))
for i, raw := range v {
tags[i] = raw.(string)
}
} }
registration := consulapi.CatalogRegistration{ registration := &consulapi.CatalogRegistration{
Address: address, Address: address,
Datacenter: dc, Datacenter: dc,
Node: node, Node: node,
Service: &consulapi.AgentService{ Service: &consulapi.AgentService{
Address: serviceData["address"].(string), Address: serviceData["address"].(string),
ID: serviceData["id"].(string), ID: serviceID,
Service: serviceData["name"].(string), Service: serviceData["name"].(string),
Port: serviceData["port"].(int), Port: serviceData["port"].(int),
Tags: tags, Tags: tags,
}, },
} }
if _, err := catalog.Register(&registration, &wOpts); err != nil { if _, err := catalog.Register(registration, &wOpts); err != nil {
return fmt.Errorf("Failed to register Consul catalog entry with node '%s' at address '%s' in %s: %v", return fmt.Errorf("Failed to register Consul catalog entry with node '%s' at address '%s' in %s: %v",
node, address, dc, err) node, address, dc, err)
} }
} }
} else { } else {
registration := consulapi.CatalogRegistration{ registration := &consulapi.CatalogRegistration{
Address: address, Address: address,
Datacenter: dc, Datacenter: dc,
Node: node, Node: node,
} }
if _, err := catalog.Register(&registration, &wOpts); err != nil { if _, err := catalog.Register(registration, &wOpts); err != nil {
return fmt.Errorf("Failed to register Consul catalog entry with node '%s' at address '%s' in %s: %v", return fmt.Errorf("Failed to register Consul catalog entry with node '%s' at address '%s' in %s: %v",
node, address, dc, err) node, address, dc, err)
} }
@ -159,7 +192,12 @@ func resourceConsulCatalogEntryCreate(d *schema.ResourceData, meta interface{})
} else { } else {
d.Set("datacenter", dc) d.Set("datacenter", dc)
} }
d.SetId(fmt.Sprintf("consul-catalog-node-%s-%s", node, address))
sort.Strings(serviceIDs)
serviceIDsJoined := strings.Join(serviceIDs, ",")
d.SetId(fmt.Sprintf("%s-%s-[%s]", node, address, serviceIDsJoined))
return nil return nil
} }
@ -189,10 +227,14 @@ func resourceConsulCatalogEntryDelete(d *schema.ResourceData, meta interface{})
client := meta.(*consulapi.Client) client := meta.(*consulapi.Client)
catalog := client.Catalog() catalog := client.Catalog()
// Get the DC, error if not available.
var dc string var dc string
if v, ok := d.GetOk("datacenter"); ok { if v, ok := d.GetOk("datacenter"); ok {
dc = v.(string) dc = v.(string)
} else {
var err error
if dc, err = getDC(client); err != nil {
return err
}
} }
var token string var token string
@ -207,7 +249,9 @@ func resourceConsulCatalogEntryDelete(d *schema.ResourceData, meta interface{})
node := d.Get("node").(string) node := d.Get("node").(string)
deregistration := consulapi.CatalogDeregistration{ deregistration := consulapi.CatalogDeregistration{
Node: node, Address: address, Datacenter: dc, Address: address,
Datacenter: dc,
Node: node,
} }
if _, err := catalog.Deregister(&deregistration, &wOpts); err != nil { if _, err := catalog.Deregister(&deregistration, &wOpts); err != nil {