github.com/huiliang/nomad@v0.2.1-0.20151124023127-7a8b664699ff/client/fingerprint/consul.go (about)

     1  package fingerprint
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strconv"
     7  	"time"
     8  
     9  	consul "github.com/hashicorp/consul/api"
    10  
    11  	client "github.com/hashicorp/nomad/client/config"
    12  	"github.com/hashicorp/nomad/nomad/structs"
    13  )
    14  
    15  // ConsulFingerprint is used to fingerprint the architecture
    16  type ConsulFingerprint struct {
    17  	logger *log.Logger
    18  	client *consul.Client
    19  }
    20  
    21  // NewConsulFingerprint is used to create an OS fingerprint
    22  func NewConsulFingerprint(logger *log.Logger) Fingerprint {
    23  	f := &ConsulFingerprint{logger: logger}
    24  	return f
    25  }
    26  
    27  func (f *ConsulFingerprint) Fingerprint(config *client.Config, node *structs.Node) (bool, error) {
    28  	// Guard against uninitialized Links
    29  	if node.Links == nil {
    30  		node.Links = map[string]string{}
    31  	}
    32  
    33  	// Only create the client once to avoid creating too many connections to
    34  	// Consul.
    35  	if f.client == nil {
    36  		address := config.ReadDefault("consul.address", "127.0.0.1:8500")
    37  		timeout, err := time.ParseDuration(config.ReadDefault("consul.timeout", "10ms"))
    38  		if err != nil {
    39  			return false, fmt.Errorf("Unable to parse consul.timeout: %s", err)
    40  		}
    41  
    42  		consulConfig := consul.DefaultConfig()
    43  		consulConfig.Address = address
    44  		consulConfig.HttpClient.Timeout = timeout
    45  
    46  		f.client, err = consul.NewClient(consulConfig)
    47  		if err != nil {
    48  			return false, fmt.Errorf("Failed to initialize consul client: %s", err)
    49  		}
    50  	}
    51  
    52  	// We'll try to detect consul by making a query to to the agent's self API.
    53  	// If we can't hit this URL consul is probably not running on this machine.
    54  	info, err := f.client.Agent().Self()
    55  	if err != nil {
    56  		// Clear any attributes set by a previous fingerprint.
    57  		f.clearConsulAttributes(node)
    58  		return false, nil
    59  	}
    60  
    61  	node.Attributes["consul.server"] = strconv.FormatBool(info["Config"]["Server"].(bool))
    62  	node.Attributes["consul.version"] = info["Config"]["Version"].(string)
    63  	node.Attributes["consul.revision"] = info["Config"]["Revision"].(string)
    64  	node.Attributes["consul.name"] = info["Config"]["NodeName"].(string)
    65  	node.Attributes["consul.datacenter"] = info["Config"]["Datacenter"].(string)
    66  
    67  	node.Links["consul"] = fmt.Sprintf("%s.%s",
    68  		node.Attributes["consul.datacenter"],
    69  		node.Attributes["consul.name"])
    70  
    71  	return true, nil
    72  }
    73  
    74  // clearConsulAttributes removes consul attributes and links from the passed
    75  // Node.
    76  func (f *ConsulFingerprint) clearConsulAttributes(n *structs.Node) {
    77  	delete(n.Attributes, "consul.server")
    78  	delete(n.Attributes, "consul.version")
    79  	delete(n.Attributes, "consul.revision")
    80  	delete(n.Attributes, "consul.name")
    81  	delete(n.Attributes, "consul.datacenter")
    82  	delete(n.Links, "consul")
    83  }
    84  
    85  func (f *ConsulFingerprint) Periodic() (bool, time.Duration) {
    86  	return true, 15 * time.Second
    87  }