command/agent: Google Compute Engine host discovery
This commit adds several command-line and config options that facilitate host discovery through Google Compute Engine (GCE), much like the recently added EC2 host discovery options. This should assist with bootstrapping and joining servers within GCE when non-static addresses are used, such as when using managed instance groups. Documentation has also been added. It should be noted that if running from within a GCE instance, the only option that should be necessary is -retry-join-gce-tag-value.
This commit is contained in:
parent
75f068accc
commit
1b4e26d005
|
@ -1,11 +1,14 @@
|
|||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
|
@ -15,6 +18,10 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/google"
|
||||
compute "google.golang.org/api/compute/v1"
|
||||
|
||||
"github.com/armon/go-metrics"
|
||||
"github.com/armon/go-metrics/circonus"
|
||||
"github.com/armon/go-metrics/datadog"
|
||||
|
@ -132,6 +139,14 @@ func (c *Command) readConfig() *Config {
|
|||
"EC2 tag key to filter on for server discovery")
|
||||
cmdFlags.StringVar(&cmdConfig.RetryJoinEC2.TagValue, "retry-join-ec2-tag-value", "",
|
||||
"EC2 tag value to filter on for server discovery")
|
||||
cmdFlags.StringVar(&cmdConfig.RetryJoinGCE.ProjectName, "retry-join-gce-project-name", "",
|
||||
"Google Compute Engine project to discover servers in")
|
||||
cmdFlags.StringVar(&cmdConfig.RetryJoinGCE.ZonePattern, "retry-join-gce-zone-pattern", "",
|
||||
"Google Compute Engine region or zone to discover servers in (regex pattern)")
|
||||
cmdFlags.StringVar(&cmdConfig.RetryJoinGCE.TagValue, "retry-join-gce-tag-value", "",
|
||||
"Google Compute Engine tag value to filter on for server discovery")
|
||||
cmdFlags.StringVar(&cmdConfig.RetryJoinGCE.CredentialsFile, "retry-join-gce-credentials-file", "",
|
||||
"Path to credentials JSON file to use with Google Compute Engine")
|
||||
cmdFlags.Var((*AppendSliceValue)(&cmdConfig.RetryJoinWan), "retry-join-wan",
|
||||
"address of agent to join -wan on startup with retry")
|
||||
cmdFlags.IntVar(&cmdConfig.RetryMaxAttemptsWan, "retry-max-wan", 0,
|
||||
|
@ -352,6 +367,12 @@ func (c *Command) readConfig() *Config {
|
|||
}
|
||||
}
|
||||
|
||||
// EC2 and GCE discovery are mutually exclusive
|
||||
if config.RetryJoinEC2.TagKey != "" && config.RetryJoinEC2.TagValue != "" && config.RetryJoinGCE.TagValue != "" {
|
||||
c.Ui.Error("EC2 and GCE discovery are mutually exclusive. Please provide one or the other.")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set the version info
|
||||
config.Revision = c.Revision
|
||||
config.Version = c.Version
|
||||
|
@ -465,6 +486,152 @@ func (c *Config) discoverEc2Hosts(logger *log.Logger) ([]string, error) {
|
|||
return servers, nil
|
||||
}
|
||||
|
||||
// discoverGCEHosts searches a Google Compute Engine region, returning a list
|
||||
// of instance ips that match the tags given in GCETags.
|
||||
func (c *Config) discoverGCEHosts(logger *log.Logger) ([]string, error) {
|
||||
config := c.RetryJoinGCE
|
||||
ctx := oauth2.NoContext
|
||||
var client *http.Client
|
||||
var err error
|
||||
|
||||
logger.Printf("[INFO] agent: Initializing GCE client")
|
||||
if config.CredentialsFile != "" {
|
||||
logger.Printf("[INFO] agent: Loading credentials from %s", config.CredentialsFile)
|
||||
key, err := ioutil.ReadFile(config.CredentialsFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jwtConfig, err := google.JWTConfigFromJSON(key, compute.ComputeScope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client = jwtConfig.Client(ctx)
|
||||
} else {
|
||||
logger.Printf("[INFO] agent: Using default credential chain")
|
||||
client, err = google.DefaultClient(ctx, compute.ComputeScope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
computeService, err := compute.New(client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if config.ProjectName == "" {
|
||||
logger.Printf("[INFO] agent: No GCE project provided, will discover from metadata.")
|
||||
config.ProjectName, err = gceProjectIDFromMetadata(logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
logger.Printf("[INFO] agent: Using pre-defined GCE project name: %s", config.ProjectName)
|
||||
}
|
||||
|
||||
zones, err := gceDiscoverZones(logger, ctx, computeService, config.ProjectName, config.ZonePattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logger.Printf("[INFO] agent: Discovering GCE hosts with tag %s in zones: %s", config.TagValue, strings.Join(zones, ", "))
|
||||
|
||||
servers := []string{}
|
||||
for _, zone := range zones {
|
||||
addresses, err := gceInstancesAddressesForZone(logger, ctx, computeService, config.ProjectName, zone, config.TagValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
servers = append(servers, addresses...)
|
||||
}
|
||||
|
||||
logger.Printf("[INFO] agent: Discovered hosts: %s", strings.Join(servers, ", "))
|
||||
|
||||
return servers, nil
|
||||
}
|
||||
|
||||
// gceProjectIDFromMetadata queries the metadata service on GCE to get the
|
||||
// project ID (name) of an instance.
|
||||
func gceProjectIDFromMetadata(logger *log.Logger) (string, error) {
|
||||
logger.Printf("[INFO] agent: Attempting to discover GCE project from metadata.")
|
||||
client := &http.Client{}
|
||||
|
||||
req, err := http.NewRequest("GET", "http://metadata.google.internal/computeMetadata/v1/project/project-id", nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
req.Header.Add("Metadata-Flavor", "Google")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
project, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
logger.Printf("[INFO] agent: GCE project discovered as: %s", project)
|
||||
return string(project), nil
|
||||
}
|
||||
|
||||
// gceDiscoverZones discovers a list of zones from a supplied zone pattern, or
|
||||
// all of the zones available to a project.
|
||||
func gceDiscoverZones(logger *log.Logger, ctx context.Context, computeService *compute.Service, project, pattern string) ([]string, error) {
|
||||
zones := []string{}
|
||||
|
||||
if pattern != "" {
|
||||
logger.Printf("[INFO] agent: Discovering zones for project %s matching pattern: %s", project, pattern)
|
||||
} else {
|
||||
logger.Printf("[INFO] agent: Discovering all zones available to project: %s", project)
|
||||
}
|
||||
|
||||
call := computeService.Zones.List(project)
|
||||
if pattern != "" {
|
||||
call = call.Filter(fmt.Sprintf("name eq %s", pattern))
|
||||
}
|
||||
|
||||
if err := call.Pages(ctx, func(page *compute.ZoneList) error {
|
||||
for _, v := range page.Items {
|
||||
zones = append(zones, v.Name)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return zones, err
|
||||
}
|
||||
|
||||
logger.Printf("[INFO] agent: Discovered GCE zones: %s", strings.Join(zones, ", "))
|
||||
return zones, nil
|
||||
}
|
||||
|
||||
// gceInstancesAddressesForZone locates all instances within a specific project
|
||||
// and zone, matching the supplied tag. Only the private IP addresses are
|
||||
// returned, but ID is also logged.
|
||||
func gceInstancesAddressesForZone(logger *log.Logger, ctx context.Context, computeService *compute.Service, project, zone, tag string) ([]string, error) {
|
||||
addresses := []string{}
|
||||
logger.Printf("[INFO] agent: Discovering instances in %s/%s matching tag: %s", project, zone, tag)
|
||||
call := computeService.Instances.List(project, zone)
|
||||
if err := call.Pages(ctx, func(page *compute.InstanceList) error {
|
||||
for _, v := range page.Items {
|
||||
for _, t := range v.Tags.Items {
|
||||
if t == tag && len(v.NetworkInterfaces) > 0 && v.NetworkInterfaces[0].NetworkIP != "" {
|
||||
logger.Printf("[INFO] agent: Discovered instance: %s -> %s", v.Name, v.NetworkInterfaces[0].NetworkIP)
|
||||
addresses = append(addresses, v.NetworkInterfaces[0].NetworkIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return addresses, err
|
||||
}
|
||||
|
||||
return addresses, nil
|
||||
}
|
||||
|
||||
// setupAgent is used to start the agent and various interfaces
|
||||
func (c *Command) setupAgent(config *Config, logOutput io.Writer, logWriter *logger.LogWriter) error {
|
||||
c.Ui.Output("Starting Consul agent...")
|
||||
|
@ -631,7 +798,7 @@ func (c *Command) startupJoinWan(config *Config) error {
|
|||
func (c *Command) retryJoin(config *Config, errCh chan<- struct{}) {
|
||||
ec2Enabled := config.RetryJoinEC2.TagKey != "" && config.RetryJoinEC2.TagValue != ""
|
||||
|
||||
if len(config.RetryJoin) == 0 && !ec2Enabled {
|
||||
if len(config.RetryJoin) == 0 && !ec2Enabled && config.RetryJoinGCE.TagValue == "" {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -642,12 +809,19 @@ func (c *Command) retryJoin(config *Config, errCh chan<- struct{}) {
|
|||
for {
|
||||
var servers []string
|
||||
var err error
|
||||
if ec2Enabled {
|
||||
switch {
|
||||
case ec2Enabled:
|
||||
servers, err = config.discoverEc2Hosts(logger)
|
||||
if err != nil {
|
||||
logger.Printf("[ERROR] agent: Unable to query EC2 insances: %s", err)
|
||||
}
|
||||
logger.Printf("[INFO] agent: Discovered %d servers from EC2...", len(servers))
|
||||
case config.RetryJoinGCE.TagValue != "":
|
||||
servers, err = config.discoverGCEHosts(logger)
|
||||
if err != nil {
|
||||
logger.Printf("[ERROR] agent: Unable to query GCE insances: %s", err)
|
||||
}
|
||||
logger.Printf("[INFO] agent: Discovered %d servers from GCE.", len(servers))
|
||||
}
|
||||
|
||||
servers = append(servers, config.RetryJoin...)
|
||||
|
@ -1165,57 +1339,83 @@ Usage: consul agent [options]
|
|||
|
||||
Options:
|
||||
|
||||
-advertise=addr Sets the advertise address to use
|
||||
-advertise-wan=addr Sets address to advertise on wan instead of advertise addr
|
||||
-atlas=org/name Sets the Atlas infrastructure name, enables SCADA.
|
||||
-atlas-join Enables auto-joining the Atlas cluster
|
||||
-atlas-token=token Provides the Atlas API token
|
||||
-atlas-endpoint=1.2.3.4 The address of the endpoint for Atlas integration.
|
||||
-bootstrap Sets server to bootstrap mode
|
||||
-bind=0.0.0.0 Sets the bind address for cluster communication
|
||||
-http-port=8500 Sets the HTTP API port to listen on
|
||||
-bootstrap-expect=0 Sets server to expect bootstrap mode.
|
||||
-client=127.0.0.1 Sets the address to bind for client access.
|
||||
This includes RPC, DNS, HTTP and HTTPS (if configured)
|
||||
-config-file=foo Path to a JSON file to read configuration from.
|
||||
This can be specified multiple times.
|
||||
-config-dir=foo Path to a directory to read configuration files
|
||||
from. This will read every file ending in ".json"
|
||||
as configuration in this directory in alphabetical
|
||||
order. This can be specified multiple times.
|
||||
-data-dir=path Path to a data directory to store agent state
|
||||
-dev Starts the agent in development mode.
|
||||
-recursor=1.2.3.4 Address of an upstream DNS server.
|
||||
Can be specified multiple times.
|
||||
-dc=east-aws Datacenter of the agent (deprecated: use 'datacenter' instead).
|
||||
-datacenter=east-aws Datacenter of the agent.
|
||||
-encrypt=key Provides the gossip encryption key
|
||||
-join=1.2.3.4 Address of an agent to join at start time.
|
||||
Can be specified multiple times.
|
||||
-join-wan=1.2.3.4 Address of an agent to join -wan at start time.
|
||||
Can be specified multiple times.
|
||||
-retry-join=1.2.3.4 Address of an agent to join at start time with
|
||||
retries enabled. Can be specified multiple times.
|
||||
-retry-interval=30s Time to wait between join attempts.
|
||||
-retry-max=0 Maximum number of join attempts. Defaults to 0, which
|
||||
will retry indefinitely.
|
||||
-retry-join-ec2-region EC2 Region to use for discovering servers to join.
|
||||
-retry-join-ec2-tag-key EC2 tag key to filter on for server discovery
|
||||
-retry-join-ec2-tag-value EC2 tag value to filter on for server discovery
|
||||
-retry-join-wan=1.2.3.4 Address of an agent to join -wan at start time with
|
||||
retries enabled. Can be specified multiple times.
|
||||
-retry-interval-wan=30s Time to wait between join -wan attempts.
|
||||
-retry-max-wan=0 Maximum number of join -wan attempts. Defaults to 0, which
|
||||
will retry indefinitely.
|
||||
-log-level=info Log level of the agent.
|
||||
-node=hostname Name of this node. Must be unique in the cluster
|
||||
-protocol=N Sets the protocol version. Defaults to latest.
|
||||
-rejoin Ignores a previous leave and attempts to rejoin the cluster.
|
||||
-server Switches agent to server mode.
|
||||
-syslog Enables logging to syslog
|
||||
-ui Enables the built-in static web UI server
|
||||
-ui-dir=path Path to directory containing the Web UI resources
|
||||
-pid-file=path Path to file to store agent PID
|
||||
-advertise=addr Sets the advertise address to use
|
||||
-advertise-wan=addr Sets address to advertise on wan instead of
|
||||
advertise addr
|
||||
-atlas=org/name Sets the Atlas infrastructure name, enables
|
||||
SCADA.
|
||||
-atlas-join Enables auto-joining the Atlas cluster
|
||||
-atlas-token=token Provides the Atlas API token
|
||||
-atlas-endpoint=1.2.3.4 The address of the endpoint for Atlas
|
||||
integration.
|
||||
-bootstrap Sets server to bootstrap mode
|
||||
-bind=0.0.0.0 Sets the bind address for cluster
|
||||
communication
|
||||
-http-port=8500 Sets the HTTP API port to listen on
|
||||
-bootstrap-expect=0 Sets server to expect bootstrap mode.
|
||||
-client=127.0.0.1 Sets the address to bind for client access.
|
||||
This includes RPC, DNS, HTTP and HTTPS (if
|
||||
configured)
|
||||
-config-file=foo Path to a JSON file to read configuration
|
||||
from. This can be specified multiple times.
|
||||
-config-dir=foo Path to a directory to read configuration
|
||||
files from. This will read every file ending
|
||||
in ".json" as configuration in this
|
||||
directory in alphabetical order. This can be
|
||||
specified multiple times.
|
||||
-data-dir=path Path to a data directory to store agent
|
||||
state
|
||||
-dev Starts the agent in development mode.
|
||||
-recursor=1.2.3.4 Address of an upstream DNS server.
|
||||
Can be specified multiple times.
|
||||
-dc=east-aws Datacenter of the agent (deprecated: use
|
||||
'datacenter' instead).
|
||||
-datacenter=east-aws Datacenter of the agent.
|
||||
-encrypt=key Provides the gossip encryption key
|
||||
-join=1.2.3.4 Address of an agent to join at start time.
|
||||
Can be specified multiple times.
|
||||
-join-wan=1.2.3.4 Address of an agent to join -wan at start
|
||||
time. Can be specified multiple times.
|
||||
-retry-join=1.2.3.4 Address of an agent to join at start time
|
||||
with retries enabled. Can be specified
|
||||
multiple times.
|
||||
-retry-interval=30s Time to wait between join attempts.
|
||||
-retry-max=0 Maximum number of join attempts. Defaults to
|
||||
0, which will retry indefinitely.
|
||||
-retry-join-ec2-region EC2 Region to use for discovering servers to
|
||||
join.
|
||||
-retry-join-ec2-tag-key EC2 tag key to filter on for server
|
||||
discovery
|
||||
-retry-join-ec2-tag-value EC2 tag value to filter on for server
|
||||
discovery
|
||||
-retry-join-gce-project-name Google Compute Engine project to discover
|
||||
servers in
|
||||
-retry-join-gce-zone-pattern Google Compute Engine region or zone to
|
||||
discover servers in (regex pattern)
|
||||
-retry-join-gce-tag-value Google Compute Engine tag value to filter
|
||||
for server discovery
|
||||
-retry-join-gce-credentials-file Path to credentials JSON file to use with
|
||||
Google Compute Engine
|
||||
-retry-join-wan=1.2.3.4 Address of an agent to join -wan at start
|
||||
time with retries enabled. Can be specified
|
||||
multiple times.
|
||||
-retry-interval-wan=30s Time to wait between join -wan attempts.
|
||||
-retry-max-wan=0 Maximum number of join -wan attempts.
|
||||
Defaults to 0, which will retry
|
||||
indefinitely.
|
||||
-log-level=info Log level of the agent.
|
||||
-node=hostname Name of this node. Must be unique in the
|
||||
cluster
|
||||
-protocol=N Sets the protocol version. Defaults to
|
||||
latest.
|
||||
-rejoin Ignores a previous leave and attempts to
|
||||
rejoin the cluster.
|
||||
-server Switches agent to server mode.
|
||||
-syslog Enables logging to syslog
|
||||
-ui Enables the built-in static web UI server
|
||||
-ui-dir=path Path to directory containing the Web UI
|
||||
resources
|
||||
-pid-file=path Path to file to store agent PID
|
||||
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
|
|
|
@ -305,6 +305,33 @@ func TestDiscoverEC2Hosts(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDiscoverGCEHosts(t *testing.T) {
|
||||
if os.Getenv("GCE_PROJECT") == "" {
|
||||
t.Skip("GCE_PROJECT not set, skipping")
|
||||
}
|
||||
|
||||
if os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") == "" && os.Getenv("GCE_CONFIG_CREDENTIALS") == "" {
|
||||
t.Skip("GOOGLE_APPLICATION_CREDENTIALS or GCE_CONFIG_CREDENTIALS not set, skipping")
|
||||
}
|
||||
|
||||
c := &Config{
|
||||
RetryJoinGCE: RetryJoinGCE{
|
||||
ProjectName: os.Getenv("GCE_PROJECT"),
|
||||
ZonePattern: os.Getenv("GCE_ZONE"),
|
||||
TagValue: "consulrole-server",
|
||||
CredentialsFile: os.Getenv("GCE_CONFIG_CREDENTIALS"),
|
||||
},
|
||||
}
|
||||
|
||||
servers, err := c.discoverGCEHosts(log.New(os.Stderr, "", log.LstdFlags))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(servers) != 3 {
|
||||
t.Fatalf("bad: %v", servers)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetupAgent_RPCUnixSocket_FileExists(t *testing.T) {
|
||||
conf := nextConfig()
|
||||
tmpDir, err := ioutil.TempDir("", "consul")
|
||||
|
|
|
@ -132,6 +132,31 @@ type RetryJoinEC2 struct {
|
|||
SecretAccessKey string `mapstructure:"secret_access_key"`
|
||||
}
|
||||
|
||||
// RetryJoinGCE is used to configure discovery of instances via Google Compute
|
||||
// Engine's API.
|
||||
type RetryJoinGCE struct {
|
||||
// The name of the project the instances reside in.
|
||||
ProjectName string `mapstructure:"project_name"`
|
||||
|
||||
// A regular expression (RE2) pattern for the zones you want to discover the instances in.
|
||||
// Example: us-west1-.*, or us-(?west|east).*.
|
||||
ZonePattern string `mapstructure:"zone_pattern"`
|
||||
|
||||
// The tag value to search for when filtering instances.
|
||||
TagValue string `mapstructure:"tag_value"`
|
||||
|
||||
// A path to a JSON file with the service account credentials necessary to
|
||||
// connect to GCE. If this is not defined, the following chain is respected:
|
||||
// 1. A JSON file whose path is specified by the
|
||||
// GOOGLE_APPLICATION_CREDENTIALS environment variable.
|
||||
// 2. A JSON file in a location known to the gcloud command-line tool.
|
||||
// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
|
||||
// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
|
||||
// 3. On Google Compute Engine, it fetches credentials from the metadata
|
||||
// server. (In this final case any provided scopes are ignored.)
|
||||
CredentialsFile string `mapstructure:"credentials_file"`
|
||||
}
|
||||
|
||||
// Performance is used to tune the performance of Consul's subsystems.
|
||||
type Performance struct {
|
||||
// RaftMultiplier is an integer multiplier used to scale Raft timing
|
||||
|
@ -421,6 +446,9 @@ type Config struct {
|
|||
// RetryJoinEC2 configuration
|
||||
RetryJoinEC2 RetryJoinEC2 `mapstructure:"retry_join_ec2"`
|
||||
|
||||
// The config struct for the GCE tag server discovery feature.
|
||||
RetryJoinGCE RetryJoinGCE `mapstructure:"retry_join_gce"`
|
||||
|
||||
// RetryJoinWan is a list of addresses to join -wan with retry enabled.
|
||||
RetryJoinWan []string `mapstructure:"retry_join_wan"`
|
||||
|
||||
|
@ -1406,6 +1434,18 @@ func MergeConfig(a, b *Config) *Config {
|
|||
if b.RetryJoinEC2.TagValue != "" {
|
||||
result.RetryJoinEC2.TagValue = b.RetryJoinEC2.TagValue
|
||||
}
|
||||
if b.RetryJoinGCE.ProjectName != "" {
|
||||
result.RetryJoinGCE.ProjectName = b.RetryJoinGCE.ProjectName
|
||||
}
|
||||
if b.RetryJoinGCE.ZonePattern != "" {
|
||||
result.RetryJoinGCE.ZonePattern = b.RetryJoinGCE.ZonePattern
|
||||
}
|
||||
if b.RetryJoinGCE.TagValue != "" {
|
||||
result.RetryJoinGCE.TagValue = b.RetryJoinGCE.TagValue
|
||||
}
|
||||
if b.RetryJoinGCE.CredentialsFile != "" {
|
||||
result.RetryJoinGCE.CredentialsFile = b.RetryJoinGCE.CredentialsFile
|
||||
}
|
||||
if b.RetryMaxAttemptsWan != 0 {
|
||||
result.RetryMaxAttemptsWan = b.RetryMaxAttemptsWan
|
||||
}
|
||||
|
|
|
@ -985,6 +985,32 @@ func TestRetryJoinEC2(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRetryJoinGCE(t *testing.T) {
|
||||
input := `{"retry_join_gce": {
|
||||
"project_name": "test-project",
|
||||
"zone_pattern": "us-west1-a",
|
||||
"tag_value": "consul-server",
|
||||
"credentials_file": "/path/to/foo.json"
|
||||
}}`
|
||||
config, err := DecodeConfig(bytes.NewReader([]byte(input)))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if config.RetryJoinGCE.ProjectName != "test-project" {
|
||||
t.Fatalf("bad: %#v", config)
|
||||
}
|
||||
if config.RetryJoinGCE.ZonePattern != "us-west1-a" {
|
||||
t.Fatalf("bad: %#v", config)
|
||||
}
|
||||
if config.RetryJoinGCE.TagValue != "consul-server" {
|
||||
t.Fatalf("bad: %#v", config)
|
||||
}
|
||||
if config.RetryJoinGCE.CredentialsFile != "/path/to/foo.json" {
|
||||
t.Fatalf("bad: %#v", config)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeConfig_Performance(t *testing.T) {
|
||||
input := `{"performance": { "raft_multiplier": 3 }}`
|
||||
config, err := DecodeConfig(bytes.NewReader([]byte(input)))
|
||||
|
|
|
@ -212,6 +212,37 @@ will exit with an error at startup.
|
|||
will use the local instance's [EC2 metadata endpoint](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html)
|
||||
to discover the region.
|
||||
|
||||
* <a name="_retry_join_gce_tag_value"></a><a href="#_retry_join_gce_tag_value">`-retry-join-gce-tag-value`
|
||||
</a> - A Google Compute Engine instance tag to filter on. Much like the
|
||||
`-retry-join-ec2-*` options, this gives Consul the option of doing server
|
||||
discovery on [Google Compute Engine](https://cloud.google.com/compute/) by
|
||||
searching the tags assigned to any inparticular instance.
|
||||
|
||||
* <a name="_retry_join_gce_project_name"></a><a href="#_retry_join_gce_project_name">`-retry-join-gce-project-name`
|
||||
</a> - The project to search in for the tag supplied by
|
||||
[`-retry-join-gce-tag-value`](#_retry_join_gce_tag_value). If this is run
|
||||
from within a GCE instance, the default is the project the instance is
|
||||
located in.
|
||||
|
||||
* <a name="_retry_join_gce_zone_pattern"></a><a href="#_retry_join_gce_zone_pattern">`-retry-join-gce-zone-pattern`
|
||||
</a> - A regular expression that indicates the zones the tag should be
|
||||
searched in. For example, while `us-west1-a` would only search in
|
||||
`us-west1-a`, `us-west1-.*` would search in `us-west1-a` and `us-west1-b`.
|
||||
The default is to search globally.
|
||||
|
||||
* <a name="_retry_join_gce_credentials_file"></a><a href="#_retry_join_gce_credentials_file">`-retry-join-gce-credentials-file`
|
||||
</a> - The path to the JSON credentials file of the [GCE Service
|
||||
Account](https://cloud.google.com/compute/docs/access/service-accounts) that
|
||||
will be used to search for instances. Note that this can also reside in the
|
||||
following locations:
|
||||
- A path supplied by the `GOOGLE_APPLICATION_CREDENTIALS` environment
|
||||
variable
|
||||
- The `%APPDATA%/gcloud/application_default_credentials.json` file (Windows)
|
||||
or `$HOME/.config/gcloud/application_default_credentials.json` (Linux and
|
||||
other systems)
|
||||
- If none of these exist and discovery is being run from a GCE instance, the
|
||||
instance's configured service account will be used.
|
||||
|
||||
* <a name="_retry_interval"></a><a href="#_retry_interval">`-retry-interval`</a> - Time
|
||||
to wait between join attempts. Defaults to 30s.
|
||||
|
||||
|
@ -717,6 +748,25 @@ Consul will not enable TLS for the HTTP API unless the `https` port has been ass
|
|||
* `access_key_id` - The AWS access key ID to use for authentication.
|
||||
* `secret_access_key` - The AWS secret access key to use for authentication.
|
||||
|
||||
* <a name="retry_join_gce"></a><a href="#retry_join_gce">`retry_join_gce`</a> - This is a nested object
|
||||
that allows the setting of GCE-related [`-retry-join`](#_retry_join) options.
|
||||
<br><br>
|
||||
The following keys are valid:
|
||||
* `project_name` - The GCE project name. Equivalent to the<br>
|
||||
[`-retry-join-gce-project-name` command-line
|
||||
flag](#_retry_join_gce_project_name).
|
||||
* `zone_pattern` - The regular expression indicating the zones to search in.
|
||||
Equivalent to the <br>
|
||||
[`-retry-join-gce-zone-pattern` command-line
|
||||
flag](#_retry_join_gce_zone_pattern).
|
||||
* `tag_value` - The GCE instance tag value to filter on. Equivalent to the <br>
|
||||
[`-retry-join-gce-tag-value` command-line
|
||||
flag](#_retry_join_gce_tag_value).
|
||||
* `credentials_file` - The path to the GCE service account credentials file.
|
||||
Equivalent to the <br>
|
||||
[`-retry-join-gce-credentials-file` command-line
|
||||
flag](#_retry_join_gce_credentials_file).
|
||||
|
||||
* <a name="retry_interval"></a><a href="#retry_interval">`retry_interval`</a> Equivalent to the
|
||||
[`-retry-interval` command-line flag](#_retry_interval).
|
||||
|
||||
|
|
Loading…
Reference in New Issue