Skip to content

Commit 4e87e5f

Browse files
authored
Merge pull request #2570 from vancluever/f-gce-discovery
command/agent: Google Compute Engine host discovery
2 parents cae8480 + 77650c2 commit 4e87e5f

File tree

229 files changed

+154743
-56
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

229 files changed

+154743
-56
lines changed

command/agent/command.go

+256-56
Large diffs are not rendered by default.

command/agent/command_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,33 @@ func TestDiscoverEC2Hosts(t *testing.T) {
331331
}
332332
}
333333

334+
func TestDiscoverGCEHosts(t *testing.T) {
335+
if os.Getenv("GCE_PROJECT") == "" {
336+
t.Skip("GCE_PROJECT not set, skipping")
337+
}
338+
339+
if os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") == "" && os.Getenv("GCE_CONFIG_CREDENTIALS") == "" {
340+
t.Skip("GOOGLE_APPLICATION_CREDENTIALS or GCE_CONFIG_CREDENTIALS not set, skipping")
341+
}
342+
343+
c := &Config{
344+
RetryJoinGCE: RetryJoinGCE{
345+
ProjectName: os.Getenv("GCE_PROJECT"),
346+
ZonePattern: os.Getenv("GCE_ZONE"),
347+
TagValue: "consulrole-server",
348+
CredentialsFile: os.Getenv("GCE_CONFIG_CREDENTIALS"),
349+
},
350+
}
351+
352+
servers, err := c.discoverGCEHosts(log.New(os.Stderr, "", log.LstdFlags))
353+
if err != nil {
354+
t.Fatal(err)
355+
}
356+
if len(servers) != 3 {
357+
t.Fatalf("bad: %v", servers)
358+
}
359+
}
360+
334361
func TestSetupAgent_RPCUnixSocket_FileExists(t *testing.T) {
335362
conf := nextConfig()
336363
tmpDir, err := ioutil.TempDir("", "consul")

command/agent/config.go

+40
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,31 @@ type RetryJoinEC2 struct {
132132
SecretAccessKey string `mapstructure:"secret_access_key"`
133133
}
134134

135+
// RetryJoinGCE is used to configure discovery of instances via Google Compute
136+
// Engine's API.
137+
type RetryJoinGCE struct {
138+
// The name of the project the instances reside in.
139+
ProjectName string `mapstructure:"project_name"`
140+
141+
// A regular expression (RE2) pattern for the zones you want to discover the instances in.
142+
// Example: us-west1-.*, or us-(?west|east).*.
143+
ZonePattern string `mapstructure:"zone_pattern"`
144+
145+
// The tag value to search for when filtering instances.
146+
TagValue string `mapstructure:"tag_value"`
147+
148+
// A path to a JSON file with the service account credentials necessary to
149+
// connect to GCE. If this is not defined, the following chain is respected:
150+
// 1. A JSON file whose path is specified by the
151+
// GOOGLE_APPLICATION_CREDENTIALS environment variable.
152+
// 2. A JSON file in a location known to the gcloud command-line tool.
153+
// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
154+
// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
155+
// 3. On Google Compute Engine, it fetches credentials from the metadata
156+
// server. (In this final case any provided scopes are ignored.)
157+
CredentialsFile string `mapstructure:"credentials_file"`
158+
}
159+
135160
// Performance is used to tune the performance of Consul's subsystems.
136161
type Performance struct {
137162
// RaftMultiplier is an integer multiplier used to scale Raft timing
@@ -426,6 +451,9 @@ type Config struct {
426451
// RetryJoinEC2 configuration
427452
RetryJoinEC2 RetryJoinEC2 `mapstructure:"retry_join_ec2"`
428453

454+
// The config struct for the GCE tag server discovery feature.
455+
RetryJoinGCE RetryJoinGCE `mapstructure:"retry_join_gce"`
456+
429457
// RetryJoinWan is a list of addresses to join -wan with retry enabled.
430458
RetryJoinWan []string `mapstructure:"retry_join_wan"`
431459

@@ -1446,6 +1474,18 @@ func MergeConfig(a, b *Config) *Config {
14461474
if b.RetryJoinEC2.TagValue != "" {
14471475
result.RetryJoinEC2.TagValue = b.RetryJoinEC2.TagValue
14481476
}
1477+
if b.RetryJoinGCE.ProjectName != "" {
1478+
result.RetryJoinGCE.ProjectName = b.RetryJoinGCE.ProjectName
1479+
}
1480+
if b.RetryJoinGCE.ZonePattern != "" {
1481+
result.RetryJoinGCE.ZonePattern = b.RetryJoinGCE.ZonePattern
1482+
}
1483+
if b.RetryJoinGCE.TagValue != "" {
1484+
result.RetryJoinGCE.TagValue = b.RetryJoinGCE.TagValue
1485+
}
1486+
if b.RetryJoinGCE.CredentialsFile != "" {
1487+
result.RetryJoinGCE.CredentialsFile = b.RetryJoinGCE.CredentialsFile
1488+
}
14491489
if b.RetryMaxAttemptsWan != 0 {
14501490
result.RetryMaxAttemptsWan = b.RetryMaxAttemptsWan
14511491
}

command/agent/config_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,32 @@ func TestRetryJoinEC2(t *testing.T) {
10471047
}
10481048
}
10491049

1050+
func TestRetryJoinGCE(t *testing.T) {
1051+
input := `{"retry_join_gce": {
1052+
"project_name": "test-project",
1053+
"zone_pattern": "us-west1-a",
1054+
"tag_value": "consul-server",
1055+
"credentials_file": "/path/to/foo.json"
1056+
}}`
1057+
config, err := DecodeConfig(bytes.NewReader([]byte(input)))
1058+
if err != nil {
1059+
t.Fatalf("err: %s", err)
1060+
}
1061+
1062+
if config.RetryJoinGCE.ProjectName != "test-project" {
1063+
t.Fatalf("bad: %#v", config)
1064+
}
1065+
if config.RetryJoinGCE.ZonePattern != "us-west1-a" {
1066+
t.Fatalf("bad: %#v", config)
1067+
}
1068+
if config.RetryJoinGCE.TagValue != "consul-server" {
1069+
t.Fatalf("bad: %#v", config)
1070+
}
1071+
if config.RetryJoinGCE.CredentialsFile != "/path/to/foo.json" {
1072+
t.Fatalf("bad: %#v", config)
1073+
}
1074+
}
1075+
10501076
func TestDecodeConfig_Performance(t *testing.T) {
10511077
input := `{"performance": { "raft_multiplier": 3 }}`
10521078
config, err := DecodeConfig(bytes.NewReader([]byte(input)))

vendor/cloud.google.com/go/LICENSE

+202
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)