예제 #1
0
func NewConsulClient(config *consulAPI.Config) (KVClient, error) {
	var (
		c   *consulAPI.Client
		err error
	)
	if config != nil {
		c, err = consulAPI.NewClient(config)
	} else {
		c, err = consulAPI.NewClient(consulAPI.DefaultConfig())
	}
	if err != nil {
		return nil, err
	}
	maxRetries := 30
	i := 0
	for {
		leader, err := c.Status().Leader()
		if err != nil || leader == "" {
			log.Info("Waiting for consul client to be ready...")
			time.Sleep(2 * time.Second)
			i++
			if i > maxRetries {
				e := fmt.Errorf("Unable to contact consul: %s", err)
				log.Error(e)
				return nil, e
			}
		} else {
			log.Info("Consul client ready")
			break
		}
	}
	return &ConsulClient{c}, nil
}
예제 #2
0
func (s *ConsulCatalogSuite) SetUpSuite(c *check.C) {
	dockerHost := os.Getenv("DOCKER_HOST")
	if dockerHost == "" {
		// FIXME Handle windows -- see if dockerClient already handle that or not
		dockerHost = fmt.Sprintf("unix://%s", opts.DefaultUnixSocket)
	}
	// Make sure we can speak to docker
	dockerClient, err := docker.NewClient(dockerHost)
	c.Assert(err, checker.IsNil, check.Commentf("Error connecting to docker daemon"))
	s.dockerClient = dockerClient

	s.createComposeProject(c, "consul_catalog")
	err = s.composeProject.Up()
	c.Assert(err, checker.IsNil, check.Commentf("Error starting project"))

	consul, err := s.GetContainer("integration-test-consul_catalog_consul_1")
	c.Assert(err, checker.IsNil, check.Commentf("Error finding consul container"))

	s.consulIP = consul.NetworkSettings.IPAddress
	config := api.DefaultConfig()
	config.Address = s.consulIP + ":8500"
	consulClient, err := api.NewClient(config)
	if err != nil {
		c.Fatalf("Error creating consul client")
	}
	s.consulClient = consulClient

	// Wait for consul to elect itself leader
	time.Sleep(2000 * time.Millisecond)
}
예제 #3
0
func consulFactory(conf map[string]string) (Client, error) {
	path, ok := conf["path"]
	if !ok {
		return nil, fmt.Errorf("missing 'path' configuration")
	}

	config := consulapi.DefaultConfig()
	if token, ok := conf["access_token"]; ok && token != "" {
		config.Token = token
	}
	if addr, ok := conf["address"]; ok && addr != "" {
		config.Address = addr
	}
	if scheme, ok := conf["scheme"]; ok && scheme != "" {
		config.Scheme = scheme
	}

	client, err := consulapi.NewClient(config)
	if err != nil {
		return nil, err
	}

	return &ConsulClient{
		Client: client,
		Path:   path,
	}, nil
}
예제 #4
0
func NewConsulBackend(address string) (Backend, error) {
	if address == "" {
		address = "http://127.0.0.1:8500/vault"
	}
	url, err := url.Parse(address)
	if err != nil {
		return nil, maskAny(err)
	}
	path := url.Path

	// Ensure path is suffixed but not prefixed
	if !strings.HasSuffix(path, "/") {
		path += "/"
	}
	if strings.HasPrefix(path, "/") {
		path = strings.TrimPrefix(path, "/")
	}

	consulConf := api.DefaultConfig()
	consulConf.Address = url.Host

	client, err := api.NewClient(consulConf)
	if err != nil {
		return nil, maskAny(err)
	}

	return &consulBackend{
		path:   path,
		client: client,
		kv:     client.KV(),
	}, nil
}
예제 #5
0
파일: consul.go 프로젝트: jeichorn/telegraf
func (c *Consul) createAPIClient() (*api.Client, error) {
	config := api.DefaultConfig()

	if c.Address != "" {
		config.Address = c.Address
	}

	if c.Scheme != "" {
		config.Scheme = c.Scheme
	}

	if c.Datacentre != "" {
		config.Datacenter = c.Datacentre
	}

	if c.Username != "" {
		config.HttpAuth = &api.HttpBasicAuth{
			Username: c.Username,
			Password: c.Password,
		}
	}

	tlsCfg, err := internal.GetTLSConfig(
		c.SSLCert, c.SSLKey, c.SSLCA, c.InsecureSkipVerify)

	if err != nil {
		return nil, err
	}

	config.HttpClient.Transport = &http.Transport{
		TLSClientConfig: tlsCfg,
	}

	return api.NewClient(config)
}
예제 #6
0
func backupAcls(ipaddress string, token string, outfile string) {

	config := api.DefaultConfig()
	config.Address = ipaddress
	config.Token = token

	client, _ := api.NewClient(config)
	acl := client.ACL()

	tokens, _, err := acl.List(nil)
	if err != nil {
		panic(err)
	}
	// sort.Sort(ByCreateIndex(tokens))

	outstring := ""
	for _, element := range tokens {
		// outstring += fmt.Sprintf("%s:%s:%s:%s\n", element.ID, element.Name, element.Type, element.Rules)
		outstring += fmt.Sprintf("====\nID: %s\nName: %s\nType: %s\nRules:\n%s\n", element.ID, element.Name, element.Type, element.Rules)
	}

	file, err := os.Create(outfile)
	if err != nil {
		panic(err)
	}

	if _, err := file.Write([]byte(outstring)[:]); err != nil {
		panic(err)
	}
}
예제 #7
0
func NewConsulClient() (ConsulClient, error) {
	client, err := consul.NewClient(consul.DefaultConfig())
	if err != nil {
		return ConsulClient{}, err
	}
	return ConsulClient{client: client}, nil
}
예제 #8
0
// Sources implements the TargetProvider interface.
func (cd *ConsulDiscovery) Sources() []string {
	clientConf := *cd.clientConf
	clientConf.HttpClient = &http.Client{Timeout: 5 * time.Second}

	client, err := consul.NewClient(&clientConf)
	if err != nil {
		// NewClient always returns a nil error.
		panic(fmt.Errorf("discovery.ConsulDiscovery.Sources: %s", err))
	}

	srvs, _, err := client.Catalog().Services(nil)
	if err != nil {
		log.Errorf("Error refreshing service list: %s", err)
		return nil
	}
	cd.mu.Lock()
	defer cd.mu.Unlock()

	srcs := make([]string, 0, len(srvs))
	for name := range srvs {
		if _, ok := cd.scrapedServices[name]; ok {
			srcs = append(srcs, consulSourcePrefix+":"+name)
		}
	}
	return srcs
}
예제 #9
0
/* File needs to be in the following format:
   KEY1:VALUE1
   KEY2:VALUE2
*/
func restoreKv(ipaddress string, token string, infile string) {

	config := api.DefaultConfig()
	config.Address = ipaddress
	config.Token = token

	data, err := ioutil.ReadFile(infile)
	if err != nil {
		panic(err)
	}

	client, _ := api.NewClient(config)
	kv := client.KV()

	for _, element := range strings.Split(string(data), "\n") {
		split := strings.Split(element, ":")
		key := strings.Join(split[:len(split)-1], ":")
		value := split[len(split)-1]

		if key != "" {
			decoded_value, decode_err := base64.StdEncoding.DecodeString(value)
			if decode_err != nil {
				panic(decode_err)
			}

			p := &api.KVPair{Key: key, Value: decoded_value}
			_, err := kv.Put(p, nil)
			if err != nil {
				panic(err)
			}
		}
	}
}
예제 #10
0
// NewDiscovery returns a new Discovery for the given config.
func NewDiscovery(conf *config.ConsulSDConfig) (*Discovery, error) {
	clientConf := &consul.Config{
		Address:    conf.Server,
		Scheme:     conf.Scheme,
		Datacenter: conf.Datacenter,
		Token:      conf.Token,
		HttpAuth: &consul.HttpBasicAuth{
			Username: conf.Username,
			Password: conf.Password,
		},
	}
	client, err := consul.NewClient(clientConf)
	if err != nil {
		return nil, err
	}
	cd := &Discovery{
		client:          client,
		clientConf:      clientConf,
		tagSeparator:    conf.TagSeparator,
		watchedServices: conf.Services,
	}
	// If the datacenter isn't set in the clientConf, let's get it from the local Consul agent
	// (Consul default is to use local node's datacenter if one isn't given for a query).
	if clientConf.Datacenter == "" {
		info, err := client.Agent().Self()
		if err != nil {
			return nil, err
		}
		cd.clientDatacenter = info["Config"]["Datacenter"].(string)
	} else {
		cd.clientDatacenter = clientConf.Datacenter
	}
	return cd, nil
}
예제 #11
0
// NewSyncer returns a new consul.Syncer
func NewSyncer(consulConfig *config.ConsulConfig, shutdownCh chan struct{}, logger *log.Logger) (*Syncer, error) {
	var consulClientConfig *consul.Config
	var err error
	consulClientConfig, err = consulConfig.ApiConfig()
	if err != nil {
		return nil, err
	}

	var consulClient *consul.Client
	if consulClient, err = consul.NewClient(consulClientConfig); err != nil {
		return nil, err
	}
	consulSyncer := Syncer{
		client:            consulClient,
		logger:            logger,
		consulAvailable:   true,
		shutdownCh:        shutdownCh,
		servicesGroups:    make(map[ServiceDomain]map[ServiceKey]*consul.AgentServiceRegistration),
		checkGroups:       make(map[ServiceDomain]map[ServiceKey][]*consul.AgentCheckRegistration),
		trackedServices:   make(map[consulServiceID]*consul.AgentServiceRegistration),
		trackedChecks:     make(map[consulCheckID]*consul.AgentCheckRegistration),
		checkRunners:      make(map[consulCheckID]*CheckRunner),
		periodicCallbacks: make(map[string]types.PeriodicCallback),
	}

	return &consulSyncer, nil
}
예제 #12
0
func (consulSource *ConsulSource) Get() (map[string]interface{}, error) {
	config := consul.DefaultConfig()

	config.Address = consulSource.Address

	if consulSource.Scheme != "" {
		config.Scheme = consulSource.Scheme
	}

	client, err := consul.NewClient(config)
	if err != nil {
		return nil, err
	}

	pairs, _, err := client.KV().List(consulSource.Prefix, nil)
	if err != nil {
		return nil, err
	}

	result := make(map[string]interface{})
	for _, pair := range pairs {
		parts := strings.Split(pair.Key, "/")
		result[parts[len(parts)-1]] = string(pair.Value)
	}

	return result, nil
}
예제 #13
0
func NewSource(opts ...config.SourceOption) config.Source {
	options := config.SourceOptions{
		Name: DefaultPath,
	}

	for _, o := range opts {
		o(&options)
	}

	// use default config
	config := api.DefaultConfig()

	// check if there are any addrs
	if len(options.Hosts) > 0 {
		addr, port, err := net.SplitHostPort(options.Hosts[0])
		if ae, ok := err.(*net.AddrError); ok && ae.Err == "missing port in address" {
			port = "8500"
			addr = options.Hosts[0]
			config.Address = fmt.Sprintf("%s:%s", addr, port)
		} else if err == nil {
			config.Address = fmt.Sprintf("%s:%s", addr, port)
		}
	}

	// create the client
	client, _ := api.NewClient(config)

	return &consul{
		addr:   config.Address,
		opts:   options,
		client: client,
	}
}
예제 #14
0
func (provider *ConsulProvider) Provide(configurationChan chan<- *Configuration) {
	config := &api.Config{
		Address:    provider.Endpoint,
		Scheme:     "http",
		HttpClient: http.DefaultClient,
	}
	consulClient, _ := api.NewClient(config)
	provider.consulClient = consulClient
	if provider.Watch {
		var waitIndex uint64
		keypairs, meta, err := consulClient.KV().Keys("", "", nil)
		if keypairs == nil && err == nil {
			log.Error("Key was not found.")
		}
		waitIndex = meta.LastIndex
		go func() {
			for {
				opts := api.QueryOptions{
					WaitIndex: waitIndex,
				}
				keypairs, meta, err := consulClient.KV().Keys("", "", &opts)
				if keypairs == nil && err == nil {
					log.Error("Key  was not found.")
				}
				waitIndex = meta.LastIndex
				configuration := provider.loadConsulConfig()
				if configuration != nil {
					configurationChan <- configuration
				}
			}
		}()
	}
	configuration := provider.loadConsulConfig()
	configurationChan <- configuration
}
예제 #15
0
파일: bootstrap.go 프로젝트: petertseng/p2
func verifyConsulUp(timeout string) error {
	timeoutDur, err := time.ParseDuration(timeout)
	if err != nil {
		return err
	}
	if timeoutDur == 0 {
		return nil
	}

	config := api.DefaultConfig()
	config.Token = *consulToken
	client, err := api.NewClient(config)
	if err != nil {
		return util.Errorf("Could not construct consul client: '%s'", err)
	}
	consulIsUp := make(chan struct{})
	go func() {
		for {
			time.Sleep(200 * time.Millisecond)
			err := Ping(client)
			if err == nil {
				consulIsUp <- struct{}{}
				return
			}
		}
	}()
	select {
	case <-time.After(timeoutDur):
		return util.Errorf("Consul did not start or was not available after %v", timeoutDur)
	case <-consulIsUp:
		return nil
	}
}
예제 #16
0
func NewConsulLocker(cfg map[string]string) (*ConsulLocker, error) {
	config := initializeConsulConfig(cfg)

	client, err := api.NewClient(config)
	if err != nil {
		return nil, err
	}
	name, _ := os.Hostname()

	var ttl = api.DefaultSemaphoreSessionTTL
	if cfg["ttl"] != "" {
		ttl = cfg["ttl"]
	}

	s, err := client.SemaphoreOpts(&api.SemaphoreOptions{
		Prefix: filepath.Join("dropship/services/", cfg["prefix"]),
		Limit:  1,

		SessionTTL: ttl,

		SessionName: name,
	})
	if err != nil {
		return nil, err
	}

	l := &ConsulLocker{s}

	return l, nil
}
예제 #17
0
파일: role.go 프로젝트: edwardt/cascade
func roleList(c cli.Command) {
	client, _ := api.NewClient(api.DefaultConfig())
	agent := client.Agent()

	services, err := agent.Services()

	if err != nil {
		log.Fatalln("err: ", err)
	}

	self, err := agent.Self()

	if err != nil {
		log.Fatalln("err: ", err)
	}

	for _, service := range services {
		if service.Service == "cascade" {
			fmt.Println(self["Config"]["NodeName"], self["Config"]["AdvertiseAddr"].(string)+":")
			for _, role := range service.Tags {
				fmt.Println("  -", role)
			}
		}
	}
}
예제 #18
0
파일: service.go 프로젝트: jen20/cascade
func serviceList(c cli.Command) {
	client, _ := api.NewClient(api.DefaultConfig())
	catalog := client.Catalog()

	services, meta, err := catalog.Services(nil)

	if err != nil {
		log.Fatalln("Err:", err)
	}

	if meta.LastIndex == 0 {
		log.Fatalln("Bad: ", meta)
	}

	sorted := make([]string, 0)

	for index, _ := range services {
		sorted = append(sorted, index)
	}

	sort.Strings(sorted)

	for _, service := range sorted {
		fmt.Println("  -", service)
	}
}
예제 #19
0
// NewConsulDiscovery returns a new ConsulDiscovery for the given config.
func NewConsulDiscovery(conf *config.ConsulSDConfig) *ConsulDiscovery {
	clientConf := &consul.Config{
		Address:    conf.Server,
		Scheme:     conf.Scheme,
		Datacenter: conf.Datacenter,
		Token:      conf.Token,
		HttpAuth: &consul.HttpBasicAuth{
			Username: conf.Username,
			Password: conf.Password,
		},
	}
	client, err := consul.NewClient(clientConf)
	if err != nil {
		// NewClient always returns a nil error.
		panic(fmt.Errorf("discovery.NewConsulDiscovery: %s", err))
	}
	cd := &ConsulDiscovery{
		client:          client,
		clientConf:      clientConf,
		tagSeparator:    conf.TagSeparator,
		runDone:         make(chan struct{}),
		srvsDone:        make(chan struct{}, 1),
		scrapedServices: map[string]struct{}{},
		services:        map[string]*consulService{},
	}
	for _, name := range conf.Services {
		cd.scrapedServices[name] = struct{}{}
	}
	return cd
}
예제 #20
0
func lookupConsulServices() ([]consulapi.CatalogService, error) {
	// Get a consul client
	client, err := consulapi.NewClient(consulapi.DefaultConfig())
	if err != nil {
		return []consulapi.CatalogService{}, err
	}

	// Lookup catalog of all service names
	catalog := client.Catalog()
	services, _, err := catalog.Services(nil)
	if err != nil {
		return []consulapi.CatalogService{}, err
	}

	// Find all instances of each service
	output := []consulapi.CatalogService{}
	fmt.Println("consul services:")
	for serviceName, _ := range services {
		catalogServices, _, err := catalog.Service(serviceName, "", nil)
		if err != nil {
			return []consulapi.CatalogService{}, err
		}

		fmt.Println(serviceName)
		for _, cs := range catalogServices {
			output = append(output, *cs)
			fmt.Printf("%#v\n", cs)
		}
	}
	return output, nil
}
예제 #21
0
func backup(ipaddress string, token string, outfile string) {

	config := api.DefaultConfig()
	config.Address = ipaddress
	config.Token = token

	client, _ := api.NewClient(config)
	kv := client.KV()

	pairs, _, err := kv.List("/", nil)
	if err != nil {
		panic(err)
	}

	sort.Sort(ByCreateIndex(pairs))

	outstring := ""
	for _, element := range pairs {
		encoded_value := base64.StdEncoding.EncodeToString(element.Value)
		outstring += fmt.Sprintf("%s:%s\n", element.Key, encoded_value)
	}

	file, err := os.Create(outfile)
	if err != nil {
		panic(err)
	}

	if _, err := file.Write([]byte(outstring)[:]); err != nil {
		panic(err)
	}
}
예제 #22
0
func (s ConsulSource) Certificates() chan []tls.Certificate {
	if s.CertURL == "" {
		return nil
	}

	config, key, err := parseConsulURL(s.CertURL)
	if err != nil {
		log.Printf("[ERROR] cert: Failed to parse consul url. %s", err)
	}

	client, err := api.NewClient(config)
	if err != nil {
		log.Printf("[ERROR] cert: Failed to create consul client. %s", err)
	}

	pemBlocksCh := make(chan map[string][]byte, 1)
	go watchKV(client, key, pemBlocksCh)

	ch := make(chan []tls.Certificate, 1)
	go func() {
		for pemBlocks := range pemBlocksCh {
			certs, err := loadCertificates(pemBlocks)
			if err != nil {
				log.Printf("[ERROR] cert: Failed to load certificates. %s", err)
				continue
			}
			ch <- certs
		}
	}()
	return ch
}
예제 #23
0
/* File needs to be in the following format:
   KEY1:VALUE1
   KEY2:VALUE2
*/
func restore(ipaddress string, token string, infile string) {

	config := api.DefaultConfig()
	config.Address = ipaddress
	config.Token = token

	data, err := ioutil.ReadFile(infile)
	if err != nil {
		panic(err)
	}

	client, _ := api.NewClient(config)
	kv := client.KV()

	for _, element := range strings.Split(string(data), "\n") {
		kvp := strings.Split(element, ":")

		if len(kvp) > 1 {
			decoded_value, decode_err := base64.StdEncoding.DecodeString(kvp[1])
			if decode_err != nil {
				panic(decode_err)
			}

			p := &api.KVPair{Key: kvp[0], Value: decoded_value}
			_, err := kv.Put(p, nil)
			if err != nil {
				panic(err)
			}
		}
	}
}
예제 #24
0
func (f *Factory) New(uri *url.URL) bridge.RegistryAdapter {
	config := consulapi.DefaultConfig()
	if uri.Scheme == "consul-unix" {
		config.Address = strings.TrimPrefix(uri.String(), "consul-")
	} else if uri.Scheme == "consul-tls" {
		tlsConfigDesc := &consulapi.TLSConfig{
			Address:            uri.Host,
			CAFile:             os.Getenv("CONSUL_CACERT"),
			CertFile:           os.Getenv("CONSUL_TLSCERT"),
			KeyFile:            os.Getenv("CONSUL_TLSKEY"),
			InsecureSkipVerify: false,
		}
		tlsConfig, err := consulapi.SetupTLSConfig(tlsConfigDesc)
		if err != nil {
			log.Fatal("Cannot set up Consul TLSConfig", err)
		}
		config.Scheme = "https"
		transport := cleanhttp.DefaultPooledTransport()
		transport.TLSClientConfig = tlsConfig
		config.HttpClient.Transport = transport
		config.Address = uri.Host
	} else if uri.Host != "" {
		config.Address = uri.Host
	}
	client, err := consulapi.NewClient(config)
	if err != nil {
		log.Fatal("consul: ", uri.Scheme)
	}
	return &ConsulAdapter{client: client}
}
예제 #25
0
func TestConsulBackend(t *testing.T) {
	addr := os.Getenv("CONSUL_HTTP_ADDR")
	if addr == "" {
		t.Skipf("No consul process running, skipping test")
	}

	conf := api.DefaultConfig()
	conf.Address = addr
	client, err := api.NewClient(conf)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	randPath := fmt.Sprintf("vault-%d/", time.Now().Unix())
	defer func() {
		client.KV().DeleteTree(randPath, nil)
	}()

	logger := log.New(os.Stderr, "", log.LstdFlags)
	b, err := NewBackend("consul", logger, map[string]string{
		"address":      addr,
		"path":         randPath,
		"max_parallel": "256",
	})
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	testBackend(t, b)
	testBackend_ListPrefix(t, b)
}
예제 #26
0
func getMasterIP(clusterName string) (masterIp string, err error) {

	log.Trace(fmt.Sprintf("gpb#consul.getMasterIP() Calling out to Consul at address %s", mcConsulIP))

	consulConfig := consulapi.DefaultConfig()
	consulConfig.Address = mcConsulIP
	consulClient, err := consulapi.NewClient(consulConfig)
	if err != nil {
		log.Error(fmt.Sprintf(`gpb#consul.getMasterIP() Consul IP: %s ! %s`, mcConsulIP, err))
		return
	}

	masterNode, _, err := consulClient.Catalog().Service(fmt.Sprintf(`%s-master`, clusterName), "", nil)
	if err != nil {
		log.Error(fmt.Sprintf("gpb#consul.getMasterIP() Cluster Name: %s ! %s", clusterName, err))
		return
	}

	if len(masterNode) == 0 {
		masterIp = "0.0.0.0"
		return masterIp, errors.New("Could not find the consul master ip")
	}

	masterIp = masterNode[0].Address
	log.Trace(fmt.Sprintf("gpb#consul.getMasterIP() Found master ip for %s = %s", clusterName, masterIp))
	return masterIp, err

}
예제 #27
0
파일: consul.go 프로젝트: postfix/golib-1
// Initialize is exported
func (s *Discovery) Initialize(uris string, heartbeat uint64) error {
	parts := strings.SplitN(uris, "/", 2)
	if len(parts) < 2 {
		return fmt.Errorf("invalid format %q, missing <path>", uris)
	}
	addr := parts[0]
	path := parts[1]

	config := consul.DefaultConfig()
	config.Address = addr

	client, err := consul.NewClient(config)
	if err != nil {
		return err
	}
	s.client = client
	s.heartbeat = time.Duration(heartbeat) * time.Second
	s.prefix = path + "/"
	kv := s.client.KV()
	p := &consul.KVPair{Key: s.prefix, Value: nil}
	if _, err = kv.Put(p, nil); err != nil {
		return err
	}
	_, meta, err := kv.Get(s.prefix, nil)
	if err != nil {
		return err
	}
	s.lastIndex = meta.LastIndex
	return nil
}
예제 #28
0
파일: consul.go 프로젝트: MiLk/swarm
// New creates a new Consul client given a list
// of endpoints and optional tls config
func New(endpoints []string, options *store.Config) (store.Store, error) {
	if len(endpoints) > 1 {
		return nil, ErrMultipleEndpointsUnsupported
	}

	s := &Consul{}

	// Create Consul client
	config := api.DefaultConfig()
	s.config = config
	config.HttpClient = http.DefaultClient
	config.Address = endpoints[0]
	config.Scheme = "http"

	// Set options
	if options != nil {
		if options.TLS != nil {
			s.setTLS(options.TLS)
		}
		if options.ConnectionTimeout != 0 {
			s.setTimeout(options.ConnectionTimeout)
		}
	}

	// Creates a new client
	client, err := api.NewClient(config)
	if err != nil {
		return nil, err
	}
	s.client = client

	return s, nil
}
예제 #29
0
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *ConsulCatalog) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
	config := api.DefaultConfig()
	config.Address = provider.Endpoint
	client, err := api.NewClient(config)
	if err != nil {
		return err
	}
	provider.client = client
	provider.Constraints = append(provider.Constraints, constraints...)

	pool.Go(func(stop chan bool) {
		notify := func(err error, time time.Duration) {
			log.Errorf("Consul connection error %+v, retrying in %s", err, time)
		}
		worker := func() error {
			return provider.watch(configurationChan, stop)
		}
		err := backoff.RetryNotify(worker, backoff.NewExponentialBackOff(), notify)
		if err != nil {
			log.Fatalf("Cannot connect to consul server %+v", err)
		}
	})

	return err
}
예제 #30
0
// WorkLock - Acquire consul for cluster to aquire right to schedule tasks.
func WorkLock() (err error) {
	clusterID := os.Getenv("RDPGD_CLUSTER")
	if clusterID == "" {
		matrixName := os.Getenv(`RDPGD_MATRIX`)
		matrixNameSplit := strings.SplitAfterN(matrixName, `-`, -1)
		matrixColumn := os.Getenv(`RDPGD_MATRIX_COLUMN`)
		for i := 0; i < len(matrixNameSplit)-1; i++ {
			clusterID = clusterID + matrixNameSplit[i]
		}
		clusterID = clusterID + "c" + matrixColumn
	}

	key := fmt.Sprintf("rdpg/%s/tasks/work/lock", clusterID)
	client, _ := consulapi.NewClient(consulapi.DefaultConfig())
	workLock, err = client.LockKey(key)
	if err != nil {
		log.Error(fmt.Sprintf("tasks.WorkLock() Error Locking Work Key %s ! %s", key, err))
		return
	}

	workLockCh, err = workLock.Lock(nil) // Acquire Consul K/V Lock
	if err != nil {
		log.Error(fmt.Sprintf("tasks.WorkLock() Error Acquiring Work Key lock %s ! %s", key, err))
		return
	}

	if workLockCh == nil {
		err = fmt.Errorf(`tasks.WorkLock() Work Lock not acquired`)
	}

	return
}