2023-03-28 20:12:41 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2015-01-06 18:40:00 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2020-09-03 16:22:03 +00:00
|
|
|
"context"
|
2019-06-17 14:51:50 +00:00
|
|
|
"encoding/json"
|
2020-09-03 16:22:03 +00:00
|
|
|
"errors"
|
2019-01-07 14:39:23 +00:00
|
|
|
"fmt"
|
2019-03-21 20:04:40 +00:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"net/http/httputil"
|
2017-09-25 23:06:49 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2015-01-21 19:08:57 +00:00
|
|
|
"strings"
|
2015-01-06 18:40:00 +00:00
|
|
|
"testing"
|
2016-11-16 21:45:26 +00:00
|
|
|
"time"
|
2016-11-30 18:29:42 +00:00
|
|
|
|
2023-01-10 16:24:02 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
2018-03-27 23:50:17 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2021-08-19 20:09:42 +00:00
|
|
|
|
2023-01-27 15:17:07 +00:00
|
|
|
"github.com/hashicorp/serf/serf"
|
|
|
|
|
2021-08-19 20:09:42 +00:00
|
|
|
"github.com/hashicorp/consul/sdk/testutil"
|
|
|
|
"github.com/hashicorp/consul/sdk/testutil/retry"
|
2015-01-06 18:40:00 +00:00
|
|
|
)
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentSelf(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-06 23:26:50 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-06 23:26:50 +00:00
|
|
|
|
2015-01-06 18:40:00 +00:00
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
info, err := agent.Self()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2017-09-27 18:47:40 +00:00
|
|
|
name := info["Config"]["NodeName"].(string)
|
2015-01-06 18:40:00 +00:00
|
|
|
if name == "" {
|
|
|
|
t.Fatalf("bad: %v", info)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-08 08:31:38 +00:00
|
|
|
func TestAPI_AgentMetrics(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
2019-02-22 18:41:28 +00:00
|
|
|
s.WaitForSerfCheck(t)
|
|
|
|
|
2017-11-10 21:03:31 +00:00
|
|
|
timer := &retry.Timer{Timeout: 10 * time.Second, Wait: 500 * time.Millisecond}
|
|
|
|
retry.RunWith(timer, t, func(r *retry.R) {
|
2017-11-07 05:43:39 +00:00
|
|
|
metrics, err := agent.Metrics()
|
|
|
|
if err != nil {
|
|
|
|
r.Fatalf("err: %v", err)
|
|
|
|
}
|
2024-01-29 22:31:44 +00:00
|
|
|
hostname, err := os.Hostname()
|
|
|
|
if err != nil {
|
|
|
|
r.Fatalf("error determining hostname: %v", err)
|
|
|
|
}
|
|
|
|
metricName := fmt.Sprintf("consul.%s.runtime.alloc_bytes", hostname)
|
2017-10-25 05:09:06 +00:00
|
|
|
for _, g := range metrics.Gauges {
|
2024-01-29 22:31:44 +00:00
|
|
|
if g.Name == metricName {
|
2017-10-25 05:09:06 +00:00
|
|
|
return
|
|
|
|
}
|
2017-09-25 22:27:04 +00:00
|
|
|
}
|
2017-10-25 05:09:06 +00:00
|
|
|
r.Fatalf("missing runtime metrics")
|
|
|
|
})
|
2017-08-08 08:31:38 +00:00
|
|
|
}
|
|
|
|
|
2018-10-17 20:20:35 +00:00
|
|
|
func TestAPI_AgentHost(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
timer := &retry.Timer{}
|
|
|
|
retry.RunWith(timer, t, func(r *retry.R) {
|
|
|
|
host, err := agent.Host()
|
|
|
|
if err != nil {
|
|
|
|
r.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// CollectionTime should exist on all responses
|
|
|
|
if host["CollectionTime"] == nil {
|
|
|
|
r.Fatalf("missing host response")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentReload(t *testing.T) {
|
2016-11-30 18:29:42 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
// Create our initial empty config file, to be overwritten later
|
2017-09-25 22:26:49 +00:00
|
|
|
cfgDir := testutil.TempDir(t, "consul-config")
|
|
|
|
|
|
|
|
cfgFilePath := filepath.Join(cfgDir, "reload.json")
|
|
|
|
configFile, err := os.Create(cfgFilePath)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Unable to create file %v, got error:%v", cfgFilePath, err)
|
2016-11-30 18:29:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
c, s := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) {
|
|
|
|
conf.Args = []string{"-config-file", configFile.Name()}
|
|
|
|
})
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
// Update the config file with a service definition
|
2018-04-21 15:34:29 +00:00
|
|
|
config := `{"service":{"name":"redis", "port":1234, "Meta": {"some": "meta"}}}`
|
2022-11-10 16:26:01 +00:00
|
|
|
err = os.WriteFile(configFile.Name(), []byte(config), 0644)
|
2016-11-30 18:29:42 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = agent.Reload(); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
service, ok := services["redis"]
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("bad: %v", ok)
|
|
|
|
}
|
|
|
|
if service.Port != 1234 {
|
|
|
|
t.Fatalf("bad: %v", service.Port)
|
|
|
|
}
|
2018-04-21 15:34:29 +00:00
|
|
|
if service.Meta["some"] != "meta" {
|
|
|
|
t.Fatalf("Missing metadata some:=meta in %v", service)
|
|
|
|
}
|
2016-11-30 18:29:42 +00:00
|
|
|
}
|
|
|
|
|
2017-09-01 00:39:46 +00:00
|
|
|
func TestAPI_AgentMembersOpts(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s1 := makeClient(t)
|
|
|
|
_, s2 := makeClientWithConfig(t, nil, func(c *testutil.TestServerConfig) {
|
|
|
|
c.Datacenter = "dc2"
|
|
|
|
})
|
|
|
|
defer s1.Stop()
|
|
|
|
defer s2.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
s2.JoinWAN(t, s1.WANAddr)
|
|
|
|
|
|
|
|
members, err := agent.MembersOpts(MembersOpts{WAN: true})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(members) != 2 {
|
|
|
|
t.Fatalf("bad: %v", members)
|
|
|
|
}
|
2023-07-25 17:54:52 +00:00
|
|
|
|
|
|
|
members, err = agent.MembersOpts(MembersOpts{
|
|
|
|
WAN: true,
|
|
|
|
Filter: `Tags["dc"] == dc2`,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
require.Equal(t, 1, len(members))
|
|
|
|
|
|
|
|
members, err = agent.MembersOpts(MembersOpts{
|
|
|
|
WAN: true,
|
|
|
|
Filter: `Tags["dc"] == "not-Exist"`,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
require.Equal(t, 0, len(members))
|
|
|
|
|
|
|
|
_, err = agent.MembersOpts(MembersOpts{
|
|
|
|
WAN: true,
|
|
|
|
Filter: `Tags["dc"] == invalid-bexpr-value`,
|
|
|
|
})
|
|
|
|
require.ErrorContains(t, err, "Failed to create boolean expression evaluator")
|
2017-09-01 00:39:46 +00:00
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentMembers(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-06 23:26:50 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-06 23:26:50 +00:00
|
|
|
|
2015-01-06 18:40:00 +00:00
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
members, err := agent.Members(false)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(members) != 1 {
|
|
|
|
t.Fatalf("bad: %v", members)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-03 09:11:40 +00:00
|
|
|
func TestAPI_AgentServiceAndReplaceChecks(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
s.WaitForSerfCheck(t)
|
2023-03-10 14:36:15 +00:00
|
|
|
locality := &Locality{Region: "us-west-1", Zone: "us-west-1a"}
|
2020-02-03 09:11:40 +00:00
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
ID: "foo",
|
|
|
|
Tags: []string{"bar", "baz"},
|
|
|
|
TaggedAddresses: map[string]ServiceAddress{
|
2020-06-16 17:19:31 +00:00
|
|
|
"lan": {
|
2020-02-03 09:11:40 +00:00
|
|
|
Address: "198.18.0.1",
|
|
|
|
Port: 80,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Port: 8000,
|
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
2023-03-10 14:36:15 +00:00
|
|
|
Locality: locality,
|
2020-02-03 09:11:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
regupdate := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
ID: "foo",
|
|
|
|
Tags: []string{"bar", "baz"},
|
|
|
|
TaggedAddresses: map[string]ServiceAddress{
|
2020-06-16 17:19:31 +00:00
|
|
|
"lan": {
|
2020-02-03 09:11:40 +00:00
|
|
|
Address: "198.18.0.1",
|
|
|
|
Port: 80,
|
|
|
|
},
|
|
|
|
},
|
2023-03-10 14:36:15 +00:00
|
|
|
Port: 9000,
|
|
|
|
Locality: locality,
|
2020-02-03 09:11:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2020-09-03 16:22:03 +00:00
|
|
|
ctx := context.Background()
|
|
|
|
opts := ServiceRegisterOpts{ReplaceExistingChecks: true}.WithContext(ctx)
|
|
|
|
if err := agent.ServiceRegisterOpts(regupdate, opts); err != nil {
|
2020-02-03 09:11:40 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, ok := services["foo"]; !ok {
|
|
|
|
t.Fatalf("missing service: %#v", services)
|
|
|
|
}
|
|
|
|
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(checks) != 0 {
|
|
|
|
t.Fatalf("checks are not removed: %v", checks)
|
|
|
|
}
|
|
|
|
|
|
|
|
state, out, err := agent.AgentHealthServiceByID("foo")
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, out)
|
|
|
|
require.Equal(t, HealthPassing, state)
|
|
|
|
require.Equal(t, 9000, out.Service.Port)
|
2023-03-10 14:36:15 +00:00
|
|
|
require.Equal(t, locality, out.Service.Locality)
|
2020-02-03 09:11:40 +00:00
|
|
|
|
|
|
|
state, outs, err := agent.AgentHealthServiceByName("foo")
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, outs)
|
|
|
|
require.Equal(t, HealthPassing, state)
|
|
|
|
require.Equal(t, 9000, outs[0].Service.Port)
|
2023-03-10 14:36:15 +00:00
|
|
|
require.Equal(t, locality, outs[0].Service.Locality)
|
2020-02-03 09:11:40 +00:00
|
|
|
|
|
|
|
if err := agent.ServiceDeregister("foo"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-03 16:22:03 +00:00
|
|
|
func TestAgent_ServiceRegisterOpts_WithContextTimeout(t *testing.T) {
|
|
|
|
c, err := NewClient(DefaultConfig())
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
|
|
|
|
t.Cleanup(cancel)
|
|
|
|
|
|
|
|
opts := ServiceRegisterOpts{}.WithContext(ctx)
|
|
|
|
err = c.Agent().ServiceRegisterOpts(&AgentServiceRegistration{}, opts)
|
|
|
|
require.True(t, errors.Is(err, context.DeadlineExceeded), "expected timeout")
|
|
|
|
}
|
|
|
|
|
2023-09-25 15:24:30 +00:00
|
|
|
func TestAgent_ServiceRegisterOpts_Token(t *testing.T) {
|
|
|
|
c, s := makeACLClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
reg := &AgentServiceRegistration{Name: "example"}
|
|
|
|
opts := &ServiceRegisterOpts{}
|
|
|
|
opts.Token = "invalid"
|
|
|
|
err := c.Agent().ServiceRegisterOpts(reg, *opts)
|
|
|
|
require.EqualError(t, err, "Unexpected response code: 403 (ACL not found)")
|
|
|
|
|
|
|
|
opts.Token = "root"
|
|
|
|
err = c.Agent().ServiceRegisterOpts(reg, *opts)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
2022-12-02 17:19:52 +00:00
|
|
|
func TestAPI_NewClient_TokenFileCLIFirstPriority(t *testing.T) {
|
|
|
|
os.Setenv("CONSUL_HTTP_TOKEN_FILE", "httpTokenFile.txt")
|
|
|
|
os.Setenv("CONSUL_HTTP_TOKEN", "httpToken")
|
|
|
|
nonExistentTokenFile := "randomTokenFile.txt"
|
|
|
|
config := Config{
|
|
|
|
Token: "randomToken",
|
|
|
|
TokenFile: nonExistentTokenFile,
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err := NewClient(&config)
|
|
|
|
errorMessage := fmt.Sprintf("Error loading token file %s : open %s: no such file or directory", nonExistentTokenFile, nonExistentTokenFile)
|
|
|
|
assert.EqualError(t, err, errorMessage)
|
|
|
|
os.Unsetenv("CONSUL_HTTP_TOKEN_FILE")
|
|
|
|
os.Unsetenv("CONSUL_HTTP_TOKEN")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAPI_NewClient_TokenCLISecondPriority(t *testing.T) {
|
|
|
|
os.Setenv("CONSUL_HTTP_TOKEN_FILE", "httpTokenFile.txt")
|
|
|
|
os.Setenv("CONSUL_HTTP_TOKEN", "httpToken")
|
|
|
|
tokenString := "randomToken"
|
|
|
|
config := Config{
|
|
|
|
Token: tokenString,
|
|
|
|
}
|
|
|
|
|
|
|
|
c, err := NewClient(&config)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error Initializing new client: %v", err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, c.config.Token, tokenString)
|
|
|
|
os.Unsetenv("CONSUL_HTTP_TOKEN_FILE")
|
|
|
|
os.Unsetenv("CONSUL_HTTP_TOKEN")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAPI_NewClient_HttpTokenFileEnvVarThirdPriority(t *testing.T) {
|
|
|
|
nonExistentTokenFileEnvVar := "httpTokenFile.txt"
|
|
|
|
os.Setenv("CONSUL_HTTP_TOKEN_FILE", nonExistentTokenFileEnvVar)
|
|
|
|
os.Setenv("CONSUL_HTTP_TOKEN", "httpToken")
|
|
|
|
|
|
|
|
_, err := NewClient(DefaultConfig())
|
|
|
|
errorMessage := fmt.Sprintf("Error loading token file %s : open %s: no such file or directory", nonExistentTokenFileEnvVar, nonExistentTokenFileEnvVar)
|
|
|
|
assert.EqualError(t, err, errorMessage)
|
|
|
|
os.Unsetenv("CONSUL_HTTP_TOKEN_FILE")
|
|
|
|
os.Unsetenv("CONSUL_HTTP_TOKEN")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAPI_NewClient_TokenEnvVarFinalPriority(t *testing.T) {
|
|
|
|
httpTokenEnvVar := "httpToken"
|
|
|
|
os.Setenv("CONSUL_HTTP_TOKEN", httpTokenEnvVar)
|
|
|
|
|
|
|
|
c, err := NewClient(DefaultConfig())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error Initializing new client: %v", err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, c.config.Token, httpTokenEnvVar)
|
|
|
|
os.Unsetenv("CONSUL_HTTP_TOKEN")
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentServices(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-06 23:26:50 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-06 23:26:50 +00:00
|
|
|
|
2015-01-06 18:40:00 +00:00
|
|
|
agent := c.Agent()
|
2019-02-22 18:41:28 +00:00
|
|
|
s.WaitForSerfCheck(t)
|
2015-01-06 18:40:00 +00:00
|
|
|
|
2023-03-10 14:36:15 +00:00
|
|
|
locality := &Locality{Region: "us-west-1", Zone: "us-west-1a"}
|
2015-01-06 18:40:00 +00:00
|
|
|
reg := &AgentServiceRegistration{
|
2015-01-22 21:42:22 +00:00
|
|
|
Name: "foo",
|
2019-01-07 14:39:23 +00:00
|
|
|
ID: "foo",
|
2015-01-22 21:42:22 +00:00
|
|
|
Tags: []string{"bar", "baz"},
|
2019-06-17 14:51:50 +00:00
|
|
|
TaggedAddresses: map[string]ServiceAddress{
|
2020-06-16 17:19:31 +00:00
|
|
|
"lan": {
|
2019-06-17 14:51:50 +00:00
|
|
|
Address: "198.18.0.1",
|
|
|
|
Port: 80,
|
|
|
|
},
|
|
|
|
},
|
2015-01-22 21:42:22 +00:00
|
|
|
Port: 8000,
|
2015-01-06 18:40:00 +00:00
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
2023-03-10 14:36:15 +00:00
|
|
|
Locality: locality,
|
2015-01-06 18:40:00 +00:00
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2015-04-12 00:53:48 +00:00
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if _, ok := services["foo"]; !ok {
|
2019-01-07 14:39:23 +00:00
|
|
|
t.Fatalf("missing service: %#v", services)
|
2015-04-12 00:53:48 +00:00
|
|
|
}
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
chk, ok := checks["service:foo"]
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Checks should default to critical
|
2016-04-23 23:01:59 +00:00
|
|
|
if chk.Status != HealthCritical {
|
2015-04-12 00:53:48 +00:00
|
|
|
t.Fatalf("Bad: %#v", chk)
|
|
|
|
}
|
|
|
|
|
2019-01-07 14:39:23 +00:00
|
|
|
state, out, err := agent.AgentHealthServiceByID("foo2")
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.Nil(t, out)
|
|
|
|
require.Equal(t, HealthCritical, state)
|
|
|
|
|
|
|
|
state, out, err = agent.AgentHealthServiceByID("foo")
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, out)
|
|
|
|
require.Equal(t, HealthCritical, state)
|
|
|
|
require.Equal(t, 8000, out.Service.Port)
|
2023-03-10 14:36:15 +00:00
|
|
|
require.Equal(t, locality, out.Service.Locality)
|
2019-01-07 14:39:23 +00:00
|
|
|
|
|
|
|
state, outs, err := agent.AgentHealthServiceByName("foo")
|
|
|
|
require.Nil(t, err)
|
|
|
|
require.NotNil(t, outs)
|
|
|
|
require.Equal(t, HealthCritical, state)
|
2020-02-03 09:11:40 +00:00
|
|
|
require.Equal(t, 8000, outs[0].Service.Port)
|
2019-01-07 14:39:23 +00:00
|
|
|
|
2015-04-12 00:53:48 +00:00
|
|
|
if err := agent.ServiceDeregister("foo"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-29 16:42:19 +00:00
|
|
|
func TestAPI_AgentServicesWithFilterOpts(t *testing.T) {
|
2019-04-16 16:00:15 +00:00
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
ID: "foo",
|
|
|
|
Tags: []string{"bar", "baz"},
|
|
|
|
Port: 8000,
|
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
require.NoError(t, agent.ServiceRegister(reg))
|
|
|
|
|
|
|
|
reg = &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
ID: "foo2",
|
|
|
|
Tags: []string{"foo", "baz"},
|
|
|
|
Port: 8001,
|
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
require.NoError(t, agent.ServiceRegister(reg))
|
|
|
|
|
2022-08-31 21:15:32 +00:00
|
|
|
opts := &QueryOptions{Namespace: defaultNamespace}
|
2021-01-29 16:42:19 +00:00
|
|
|
services, err := agent.ServicesWithFilterOpts("foo in Tags", opts)
|
2019-04-16 16:00:15 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, services, 1)
|
|
|
|
_, ok := services["foo2"]
|
|
|
|
require.True(t, ok)
|
|
|
|
}
|
|
|
|
|
2018-09-27 13:33:12 +00:00
|
|
|
func TestAPI_AgentServices_SidecarService(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
// Register service
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
Port: 8000,
|
|
|
|
Connect: &AgentServiceConnect{
|
|
|
|
SidecarService: &AgentServiceRegistration{},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if _, ok := services["foo"]; !ok {
|
|
|
|
t.Fatalf("missing service: %v", services)
|
|
|
|
}
|
|
|
|
if _, ok := services["foo-sidecar-proxy"]; !ok {
|
|
|
|
t.Fatalf("missing sidecar service: %v", services)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := agent.ServiceDeregister("foo"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Deregister should have removed both service and it's sidecar
|
|
|
|
services, err = agent.Services()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
if _, ok := services["foo"]; ok {
|
|
|
|
t.Fatalf("didn't remove service: %v", services)
|
|
|
|
}
|
|
|
|
if _, ok := services["foo-sidecar-proxy"]; ok {
|
|
|
|
t.Fatalf("didn't remove sidecar service: %v", services)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-20 13:24:24 +00:00
|
|
|
func TestAPI_AgentServices_ExternalConnectProxy(t *testing.T) {
|
2018-03-26 15:51:43 +00:00
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
// Register service
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
Port: 8000,
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
// Register proxy
|
|
|
|
reg = &AgentServiceRegistration{
|
2018-09-12 16:07:47 +00:00
|
|
|
Kind: ServiceKindConnectProxy,
|
|
|
|
Name: "foo-proxy",
|
|
|
|
Port: 8001,
|
|
|
|
Proxy: &AgentServiceConnectProxyConfig{
|
|
|
|
DestinationServiceName: "foo",
|
2021-04-12 15:35:14 +00:00
|
|
|
Mode: ProxyModeTransparent,
|
2018-09-12 16:07:47 +00:00
|
|
|
},
|
2018-03-26 15:51:43 +00:00
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if _, ok := services["foo"]; !ok {
|
|
|
|
t.Fatalf("missing service: %v", services)
|
|
|
|
}
|
|
|
|
if _, ok := services["foo-proxy"]; !ok {
|
|
|
|
t.Fatalf("missing proxy service: %v", services)
|
|
|
|
}
|
2021-04-12 15:35:14 +00:00
|
|
|
if services["foo-proxy"].Proxy.Mode != ProxyModeTransparent {
|
2021-03-11 06:08:41 +00:00
|
|
|
t.Fatalf("expected transparent proxy mode to be enabled")
|
|
|
|
}
|
2018-03-26 15:51:43 +00:00
|
|
|
|
|
|
|
if err := agent.ServiceDeregister("foo"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if err := agent.ServiceDeregister("foo-proxy"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentServices_CheckPassing(t *testing.T) {
|
2015-05-12 01:53:09 +00:00
|
|
|
t.Parallel()
|
2015-04-12 00:53:48 +00:00
|
|
|
c, s := makeClient(t)
|
2015-05-12 01:53:09 +00:00
|
|
|
defer s.Stop()
|
2015-04-12 00:53:48 +00:00
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
Tags: []string{"bar", "baz"},
|
|
|
|
Port: 8000,
|
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
2016-04-23 23:01:59 +00:00
|
|
|
Status: HealthPassing,
|
2015-04-12 00:53:48 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2015-01-06 18:40:00 +00:00
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if _, ok := services["foo"]; !ok {
|
|
|
|
t.Fatalf("missing service: %v", services)
|
|
|
|
}
|
|
|
|
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2015-04-12 00:53:48 +00:00
|
|
|
chk, ok := checks["service:foo"]
|
|
|
|
if !ok {
|
2015-01-06 18:40:00 +00:00
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
|
2016-04-23 23:01:59 +00:00
|
|
|
if chk.Status != HealthPassing {
|
2015-04-12 00:53:48 +00:00
|
|
|
t.Fatalf("Bad: %#v", chk)
|
|
|
|
}
|
2015-01-06 18:40:00 +00:00
|
|
|
if err := agent.ServiceDeregister("foo"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentServices_CheckBadStatus(t *testing.T) {
|
2015-05-12 01:53:09 +00:00
|
|
|
t.Parallel()
|
2015-04-12 00:53:48 +00:00
|
|
|
c, s := makeClient(t)
|
2015-05-12 01:53:09 +00:00
|
|
|
defer s.Stop()
|
2015-04-12 00:53:48 +00:00
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
Tags: []string{"bar", "baz"},
|
|
|
|
Port: 8000,
|
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
Status: "fluffy",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err == nil {
|
|
|
|
t.Fatalf("bad status accepted")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-08 20:59:55 +00:00
|
|
|
func TestAPI_AgentServices_CheckID(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
Tags: []string{"bar", "baz"},
|
|
|
|
Port: 8000,
|
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
CheckID: "foo-ttl",
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if _, ok := checks["foo-ttl"]; !ok {
|
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentServiceAddress(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-22 10:50:20 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-22 10:50:20 +00:00
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg1 := &AgentServiceRegistration{
|
|
|
|
Name: "foo1",
|
|
|
|
Port: 8000,
|
|
|
|
Address: "192.168.0.42",
|
|
|
|
}
|
|
|
|
reg2 := &AgentServiceRegistration{
|
2015-01-22 21:42:22 +00:00
|
|
|
Name: "foo2",
|
|
|
|
Port: 8000,
|
2019-06-17 14:51:50 +00:00
|
|
|
TaggedAddresses: map[string]ServiceAddress{
|
2020-06-16 17:19:31 +00:00
|
|
|
"lan": {
|
2019-06-17 14:51:50 +00:00
|
|
|
Address: "192.168.0.43",
|
|
|
|
Port: 8000,
|
|
|
|
},
|
2020-06-16 17:19:31 +00:00
|
|
|
"wan": {
|
2019-06-17 14:51:50 +00:00
|
|
|
Address: "198.18.0.1",
|
|
|
|
Port: 80,
|
|
|
|
},
|
|
|
|
},
|
2015-01-22 10:50:20 +00:00
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg1); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg2); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2015-01-22 21:42:22 +00:00
|
|
|
|
2015-01-22 10:50:20 +00:00
|
|
|
if _, ok := services["foo1"]; !ok {
|
|
|
|
t.Fatalf("missing service: %v", services)
|
|
|
|
}
|
|
|
|
if _, ok := services["foo2"]; !ok {
|
|
|
|
t.Fatalf("missing service: %v", services)
|
|
|
|
}
|
|
|
|
|
|
|
|
if services["foo1"].Address != "192.168.0.42" {
|
|
|
|
t.Fatalf("missing Address field in service foo1: %v", services)
|
|
|
|
}
|
|
|
|
if services["foo2"].Address != "" {
|
|
|
|
t.Fatalf("missing Address field in service foo2: %v", services)
|
|
|
|
}
|
2019-06-17 14:51:50 +00:00
|
|
|
require.NotNil(t, services["foo2"].TaggedAddresses)
|
|
|
|
require.Contains(t, services["foo2"].TaggedAddresses, "lan")
|
|
|
|
require.Contains(t, services["foo2"].TaggedAddresses, "wan")
|
|
|
|
require.Equal(t, services["foo2"].TaggedAddresses["lan"].Address, "192.168.0.43")
|
|
|
|
require.Equal(t, services["foo2"].TaggedAddresses["lan"].Port, 8000)
|
|
|
|
require.Equal(t, services["foo2"].TaggedAddresses["wan"].Address, "198.18.0.1")
|
|
|
|
require.Equal(t, services["foo2"].TaggedAddresses["wan"].Port, 80)
|
2015-01-22 10:50:20 +00:00
|
|
|
|
2021-07-15 23:54:57 +00:00
|
|
|
if err := agent.ServiceDeregister("foo1"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := agent.ServiceDeregister("foo2"); err != nil {
|
2015-01-22 10:50:20 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
2021-08-12 17:05:22 +00:00
|
|
|
func TestAPI_AgentServiceSocket(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg1 := &AgentServiceRegistration{
|
|
|
|
Name: "foo1",
|
|
|
|
Port: 8000,
|
|
|
|
Address: "192.168.0.42",
|
|
|
|
}
|
|
|
|
reg2 := &AgentServiceRegistration{
|
|
|
|
Name: "foo2",
|
|
|
|
SocketPath: "/tmp/foo2.sock",
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := agent.ServiceRegister(reg1); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg2); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
require.Contains(t, services, "foo1", "missing service foo1")
|
|
|
|
require.Contains(t, services, "foo2", "missing service foo2")
|
|
|
|
|
|
|
|
require.Equal(t, "192.168.0.42", services["foo1"].Address,
|
|
|
|
"missing Address field in service foo1: %v", services["foo1"])
|
|
|
|
|
|
|
|
require.Equal(t, "", services["foo2"].Address,
|
|
|
|
"unexpected Address field in service foo1: %v", services["foo2"])
|
|
|
|
require.Equal(t, "/tmp/foo2.sock", services["foo2"].SocketPath,
|
|
|
|
"missing SocketPath field in service foo1: %v", services["foo2"])
|
|
|
|
}
|
2015-01-22 10:50:20 +00:00
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentEnableTagOverride(t *testing.T) {
|
2016-02-16 19:45:29 +00:00
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg1 := &AgentServiceRegistration{
|
|
|
|
Name: "foo1",
|
|
|
|
Port: 8000,
|
|
|
|
Address: "192.168.0.42",
|
|
|
|
EnableTagOverride: true,
|
|
|
|
}
|
|
|
|
reg2 := &AgentServiceRegistration{
|
|
|
|
Name: "foo2",
|
|
|
|
Port: 8000,
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg1); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg2); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, ok := services["foo1"]; !ok {
|
|
|
|
t.Fatalf("missing service: %v", services)
|
|
|
|
}
|
|
|
|
if services["foo1"].EnableTagOverride != true {
|
|
|
|
t.Fatalf("tag override not set on service foo1: %v", services)
|
|
|
|
}
|
|
|
|
if _, ok := services["foo2"]; !ok {
|
|
|
|
t.Fatalf("missing service: %v", services)
|
|
|
|
}
|
|
|
|
if services["foo2"].EnableTagOverride != false {
|
|
|
|
t.Fatalf("tag override set on service foo2: %v", services)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentServices_MultipleChecks(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-14 03:18:46 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-14 03:18:46 +00:00
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
Tags: []string{"bar", "baz"},
|
|
|
|
Port: 8000,
|
|
|
|
Checks: AgentServiceChecks{
|
|
|
|
&AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
|
|
|
&AgentServiceCheck{
|
|
|
|
TTL: "30s",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if _, ok := services["foo"]; !ok {
|
|
|
|
t.Fatalf("missing service: %v", services)
|
|
|
|
}
|
|
|
|
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if _, ok := checks["service:foo:1"]; !ok {
|
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
if _, ok := checks["service:foo:2"]; !ok {
|
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-27 14:00:51 +00:00
|
|
|
func TestAPI_AgentService(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
Tags: []string{"bar", "baz"},
|
|
|
|
Port: 8000,
|
|
|
|
Checks: AgentServiceChecks{
|
|
|
|
&AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
|
|
|
&AgentServiceCheck{
|
|
|
|
TTL: "30s",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NoError(t, agent.ServiceRegister(reg))
|
2018-09-27 14:00:51 +00:00
|
|
|
|
|
|
|
got, qm, err := agent.Service("foo", nil)
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NoError(t, err)
|
2018-09-27 14:00:51 +00:00
|
|
|
|
|
|
|
expect := &AgentService{
|
|
|
|
ID: "foo",
|
|
|
|
Service: "foo",
|
|
|
|
Tags: []string{"bar", "baz"},
|
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
|
|
|
ContentHash: "3e352f348d44f7eb",
|
2018-09-27 14:00:51 +00:00
|
|
|
Port: 8000,
|
2019-01-08 10:13:49 +00:00
|
|
|
Weights: AgentWeights{
|
|
|
|
Passing: 1,
|
|
|
|
Warning: 1,
|
|
|
|
},
|
2020-11-19 21:27:31 +00:00
|
|
|
Meta: map[string]string{},
|
2022-08-31 21:15:32 +00:00
|
|
|
Namespace: defaultNamespace,
|
|
|
|
Partition: defaultPartition,
|
2020-11-19 21:27:31 +00:00
|
|
|
Datacenter: "dc1",
|
2018-09-27 14:00:51 +00:00
|
|
|
}
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.Equal(t, expect, got)
|
|
|
|
require.Equal(t, expect.ContentHash, qm.LastContentHash)
|
2018-09-27 14:00:51 +00:00
|
|
|
|
2019-01-08 10:13:49 +00:00
|
|
|
// Sanity check blocking behavior - this is more thoroughly tested in the
|
2018-09-27 14:00:51 +00:00
|
|
|
// agent endpoint tests but this ensures that the API package is at least
|
|
|
|
// passing the hash param properly.
|
|
|
|
opts := QueryOptions{
|
2019-01-08 10:13:49 +00:00
|
|
|
WaitHash: qm.LastContentHash,
|
2018-09-27 14:00:51 +00:00
|
|
|
WaitTime: 100 * time.Millisecond, // Just long enough to be reliably measurable
|
|
|
|
}
|
|
|
|
start := time.Now()
|
2020-06-05 19:28:03 +00:00
|
|
|
_, _, err = agent.Service("foo", &opts)
|
2018-09-27 14:00:51 +00:00
|
|
|
elapsed := time.Since(start)
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.True(t, elapsed >= opts.WaitTime)
|
2018-09-27 14:00:51 +00:00
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentSetTTLStatus(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-06 23:26:50 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-06 23:26:50 +00:00
|
|
|
|
2015-01-06 18:40:00 +00:00
|
|
|
agent := c.Agent()
|
2019-02-22 18:41:28 +00:00
|
|
|
s.WaitForSerfCheck(t)
|
2015-01-06 18:40:00 +00:00
|
|
|
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2016-03-04 23:18:25 +00:00
|
|
|
verify := func(status, output string) {
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
chk, ok := checks["service:foo"]
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
if chk.Status != status {
|
|
|
|
t.Fatalf("Bad: %#v", chk)
|
|
|
|
}
|
|
|
|
if chk.Output != output {
|
|
|
|
t.Fatalf("Bad: %#v", chk)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := agent.WarnTTL("service:foo", "foo"); err != nil {
|
2015-01-06 18:40:00 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
verify(HealthWarning, "foo")
|
2015-01-06 18:40:00 +00:00
|
|
|
|
2016-03-04 23:18:25 +00:00
|
|
|
if err := agent.PassTTL("service:foo", "bar"); err != nil {
|
2015-01-06 18:40:00 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
verify(HealthPassing, "bar")
|
2016-03-04 23:18:25 +00:00
|
|
|
|
|
|
|
if err := agent.FailTTL("service:foo", "baz"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
2015-01-06 18:40:00 +00:00
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
verify(HealthCritical, "baz")
|
2016-03-04 23:18:25 +00:00
|
|
|
|
|
|
|
if err := agent.UpdateTTL("service:foo", "foo", "warn"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
2015-01-06 18:40:00 +00:00
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
verify(HealthWarning, "foo")
|
2016-03-04 23:18:25 +00:00
|
|
|
|
|
|
|
if err := agent.UpdateTTL("service:foo", "bar", "pass"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
verify(HealthPassing, "bar")
|
2016-03-04 23:18:25 +00:00
|
|
|
|
|
|
|
if err := agent.UpdateTTL("service:foo", "baz", "fail"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
verify(HealthCritical, "baz")
|
2016-03-04 23:18:25 +00:00
|
|
|
|
2016-04-23 23:01:59 +00:00
|
|
|
if err := agent.UpdateTTL("service:foo", "foo", HealthWarning); err != nil {
|
2016-03-04 23:18:25 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
verify(HealthWarning, "foo")
|
2016-03-04 23:18:25 +00:00
|
|
|
|
2016-04-23 23:01:59 +00:00
|
|
|
if err := agent.UpdateTTL("service:foo", "bar", HealthPassing); err != nil {
|
2016-03-04 23:18:25 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
verify(HealthPassing, "bar")
|
2016-03-04 23:18:25 +00:00
|
|
|
|
2016-04-23 23:01:59 +00:00
|
|
|
if err := agent.UpdateTTL("service:foo", "baz", HealthCritical); err != nil {
|
2016-03-04 23:18:25 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
2015-01-06 18:40:00 +00:00
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
verify(HealthCritical, "baz")
|
2015-01-06 18:40:00 +00:00
|
|
|
|
|
|
|
if err := agent.ServiceDeregister("foo"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-29 16:42:19 +00:00
|
|
|
func TestAPI_AgentUpdateTTLOpts(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
s.WaitForSerfCheck(t)
|
|
|
|
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
verify := func(status, output string) {
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
chk, ok := checks["service:foo"]
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
if chk.Status != status {
|
|
|
|
t.Fatalf("Bad: %#v", chk)
|
|
|
|
}
|
|
|
|
if chk.Output != output {
|
|
|
|
t.Fatalf("Bad: %#v", chk)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-31 21:15:32 +00:00
|
|
|
opts := &QueryOptions{Namespace: defaultNamespace}
|
2021-01-29 16:42:19 +00:00
|
|
|
|
|
|
|
if err := agent.UpdateTTLOpts("service:foo", "foo", HealthWarning, opts); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
verify(HealthWarning, "foo")
|
|
|
|
|
|
|
|
if err := agent.UpdateTTLOpts("service:foo", "bar", HealthPassing, opts); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
verify(HealthPassing, "bar")
|
|
|
|
|
|
|
|
if err := agent.UpdateTTL("service:foo", "baz", HealthCritical); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
verify(HealthCritical, "baz")
|
|
|
|
|
|
|
|
if err := agent.ServiceDeregister("foo"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentChecks(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-06 23:26:50 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-06 23:26:50 +00:00
|
|
|
|
2015-01-06 18:40:00 +00:00
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg := &AgentCheckRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
}
|
|
|
|
reg.TTL = "15s"
|
2023-09-25 15:25:02 +00:00
|
|
|
if err := agent.CheckRegisterOpts(reg, nil); err != nil {
|
2015-01-06 18:40:00 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2015-04-12 00:53:48 +00:00
|
|
|
chk, ok := checks["foo"]
|
|
|
|
if !ok {
|
2015-01-06 18:40:00 +00:00
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
if chk.Status != HealthCritical {
|
2015-04-12 00:53:48 +00:00
|
|
|
t.Fatalf("check not critical: %v", chk)
|
|
|
|
}
|
2019-10-17 18:33:11 +00:00
|
|
|
if chk.Type != "ttl" {
|
|
|
|
t.Fatalf("expected type ttl, got %s", chk.Type)
|
|
|
|
}
|
2015-04-12 00:53:48 +00:00
|
|
|
|
|
|
|
if err := agent.CheckDeregister("foo"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-25 15:25:02 +00:00
|
|
|
func TestAgent_AgentChecksRegisterOpts_WithContextTimeout(t *testing.T) {
|
|
|
|
c, err := NewClient(DefaultConfig())
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
|
|
|
|
t.Cleanup(cancel)
|
|
|
|
|
|
|
|
opts := &QueryOptions{}
|
|
|
|
opts = opts.WithContext(ctx)
|
|
|
|
err = c.Agent().CheckRegisterOpts(&AgentCheckRegistration{}, opts)
|
|
|
|
require.True(t, errors.Is(err, context.DeadlineExceeded), "expected timeout")
|
|
|
|
}
|
|
|
|
|
2021-01-29 16:42:19 +00:00
|
|
|
func TestAPI_AgentChecksWithFilterOpts(t *testing.T) {
|
2019-04-16 16:00:15 +00:00
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg := &AgentCheckRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
}
|
|
|
|
reg.TTL = "15s"
|
|
|
|
require.NoError(t, agent.CheckRegister(reg))
|
|
|
|
reg = &AgentCheckRegistration{
|
|
|
|
Name: "bar",
|
|
|
|
}
|
|
|
|
reg.TTL = "15s"
|
|
|
|
require.NoError(t, agent.CheckRegister(reg))
|
|
|
|
|
2022-08-31 21:15:32 +00:00
|
|
|
opts := &QueryOptions{Namespace: defaultNamespace}
|
2021-01-29 16:42:19 +00:00
|
|
|
checks, err := agent.ChecksWithFilterOpts("Name == foo", opts)
|
2019-04-16 16:00:15 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, checks, 1)
|
|
|
|
_, ok := checks["foo"]
|
|
|
|
require.True(t, ok)
|
|
|
|
}
|
|
|
|
|
2017-10-18 18:28:39 +00:00
|
|
|
func TestAPI_AgentScriptCheck(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClientWithConfig(t, nil, func(c *testutil.TestServerConfig) {
|
|
|
|
c.EnableScriptChecks = true
|
|
|
|
})
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
t.Run("node script check", func(t *testing.T) {
|
|
|
|
reg := &AgentCheckRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
AgentServiceCheck: AgentServiceCheck{
|
|
|
|
Interval: "10s",
|
|
|
|
Args: []string{"sh", "-c", "false"},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := agent.CheckRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if _, ok := checks["foo"]; !ok {
|
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("service script check", func(t *testing.T) {
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "bar",
|
|
|
|
Port: 1234,
|
|
|
|
Checks: AgentServiceChecks{
|
|
|
|
&AgentServiceCheck{
|
|
|
|
Interval: "10s",
|
|
|
|
Args: []string{"sh", "-c", "false"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
services, err := agent.Services()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if _, ok := services["bar"]; !ok {
|
|
|
|
t.Fatalf("missing service: %v", services)
|
|
|
|
}
|
|
|
|
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if _, ok := checks["service:bar"]; !ok {
|
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentCheckStartPassing(t *testing.T) {
|
2015-05-12 01:53:09 +00:00
|
|
|
t.Parallel()
|
2015-04-12 00:53:48 +00:00
|
|
|
c, s := makeClient(t)
|
2015-05-12 01:53:09 +00:00
|
|
|
defer s.Stop()
|
2015-04-12 00:53:48 +00:00
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg := &AgentCheckRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
AgentServiceCheck: AgentServiceCheck{
|
2016-04-23 23:01:59 +00:00
|
|
|
Status: HealthPassing,
|
2015-04-12 00:53:48 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
reg.TTL = "15s"
|
|
|
|
if err := agent.CheckRegister(reg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
chk, ok := checks["foo"]
|
|
|
|
if !ok {
|
2015-01-06 18:40:00 +00:00
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
2016-04-23 23:01:59 +00:00
|
|
|
if chk.Status != HealthPassing {
|
2015-04-12 00:53:48 +00:00
|
|
|
t.Fatalf("check not passing: %v", chk)
|
|
|
|
}
|
2015-01-06 18:40:00 +00:00
|
|
|
|
|
|
|
if err := agent.CheckDeregister("foo"); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentChecks_serviceBound(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-14 03:18:46 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-14 03:18:46 +00:00
|
|
|
|
|
|
|
agent := c.Agent()
|
2019-02-22 18:41:28 +00:00
|
|
|
s.WaitForSerfCheck(t)
|
2015-01-14 03:18:46 +00:00
|
|
|
|
|
|
|
// First register a service
|
|
|
|
serviceReg := &AgentServiceRegistration{
|
|
|
|
Name: "redis",
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(serviceReg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register a check bound to the service
|
|
|
|
reg := &AgentCheckRegistration{
|
|
|
|
Name: "redischeck",
|
|
|
|
ServiceID: "redis",
|
|
|
|
}
|
|
|
|
reg.TTL = "15s"
|
2016-08-16 07:05:55 +00:00
|
|
|
reg.DeregisterCriticalServiceAfter = "nope"
|
|
|
|
err := agent.CheckRegister(reg)
|
|
|
|
if err == nil || !strings.Contains(err.Error(), "invalid duration") {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
reg.DeregisterCriticalServiceAfter = "90m"
|
2015-01-14 03:18:46 +00:00
|
|
|
if err := agent.CheckRegister(reg); err != nil {
|
2015-11-18 15:40:02 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
check, ok := checks["redischeck"]
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
if check.ServiceID != "redis" {
|
|
|
|
t.Fatalf("missing service association for check: %v", check)
|
|
|
|
}
|
2019-10-17 18:33:11 +00:00
|
|
|
if check.Type != "ttl" {
|
|
|
|
t.Fatalf("expected type ttl, got %s", check.Type)
|
|
|
|
}
|
2015-11-18 15:40:02 +00:00
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentChecks_Docker(t *testing.T) {
|
2015-11-18 15:40:02 +00:00
|
|
|
t.Parallel()
|
2017-07-17 18:20:35 +00:00
|
|
|
c, s := makeClientWithConfig(t, nil, func(c *testutil.TestServerConfig) {
|
|
|
|
c.EnableScriptChecks = true
|
|
|
|
})
|
2015-11-18 15:40:02 +00:00
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
// First register a service
|
|
|
|
serviceReg := &AgentServiceRegistration{
|
|
|
|
Name: "redis",
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(serviceReg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register a check bound to the service
|
|
|
|
reg := &AgentCheckRegistration{
|
|
|
|
Name: "redischeck",
|
|
|
|
ServiceID: "redis",
|
|
|
|
AgentServiceCheck: AgentServiceCheck{
|
|
|
|
DockerContainerID: "f972c95ebf0e",
|
2018-05-08 22:31:53 +00:00
|
|
|
Args: []string{"/bin/true"},
|
2015-11-18 15:40:02 +00:00
|
|
|
Shell: "/bin/bash",
|
|
|
|
Interval: "10s",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := agent.CheckRegister(reg); err != nil {
|
2015-01-14 03:18:46 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
check, ok := checks["redischeck"]
|
|
|
|
if !ok {
|
|
|
|
t.Fatalf("missing check: %v", checks)
|
|
|
|
}
|
|
|
|
if check.ServiceID != "redis" {
|
|
|
|
t.Fatalf("missing service association for check: %v", check)
|
|
|
|
}
|
2019-10-17 18:33:11 +00:00
|
|
|
if check.Type != "docker" {
|
2019-10-29 18:13:36 +00:00
|
|
|
t.Fatalf("expected type docker, got %s", check.Type)
|
2019-10-17 18:33:11 +00:00
|
|
|
}
|
2015-01-14 03:18:46 +00:00
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentJoin(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-06 23:26:50 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-06 23:26:50 +00:00
|
|
|
|
2015-01-06 18:40:00 +00:00
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
info, err := agent.Self()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Join ourself
|
2017-10-04 17:43:17 +00:00
|
|
|
addr := info["DebugConfig"]["SerfAdvertiseAddrLAN"].(string)
|
2017-09-27 18:47:40 +00:00
|
|
|
// strip off 'tcp://'
|
|
|
|
addr = addr[len("tcp://"):]
|
2015-01-06 18:40:00 +00:00
|
|
|
err = agent.Join(addr, false)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentLeave(t *testing.T) {
|
2016-11-30 18:29:42 +00:00
|
|
|
t.Parallel()
|
|
|
|
c1, s1 := makeClient(t)
|
|
|
|
defer s1.Stop()
|
|
|
|
|
|
|
|
c2, s2 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) {
|
|
|
|
conf.Server = false
|
|
|
|
conf.Bootstrap = false
|
|
|
|
})
|
|
|
|
defer s2.Stop()
|
|
|
|
|
|
|
|
if err := c2.Agent().Join(s1.LANAddr, false); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2017-01-27 06:22:18 +00:00
|
|
|
// We sometimes see an EOF response to this one, depending on timing.
|
|
|
|
err := c2.Agent().Leave()
|
2017-03-22 16:56:53 +00:00
|
|
|
if err != nil && !strings.Contains(err.Error(), "EOF") {
|
2016-11-30 18:29:42 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure the second agent's status is 'Left'
|
|
|
|
members, err := c1.Agent().Members(false)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
member := members[0]
|
|
|
|
if member.Name == s1.Config.NodeName {
|
|
|
|
member = members[1]
|
|
|
|
}
|
|
|
|
if member.Status != int(serf.StatusLeft) {
|
|
|
|
t.Fatalf("bad: %v", *member)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentForceLeave(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-06 23:26:50 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-06 23:26:50 +00:00
|
|
|
|
2015-01-06 18:40:00 +00:00
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
// Eject somebody
|
2019-12-02 19:06:15 +00:00
|
|
|
err := agent.ForceLeave(s.Config.NodeName)
|
2015-01-06 18:40:00 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
2015-01-21 18:51:26 +00:00
|
|
|
|
2019-10-04 21:10:02 +00:00
|
|
|
func TestAPI_AgentForceLeavePrune(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
// Eject somebody
|
2019-12-02 19:06:15 +00:00
|
|
|
err := agent.ForceLeavePrune(s.Config.NodeName)
|
2019-10-04 21:10:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-18 16:31:48 +00:00
|
|
|
func TestAPI_AgentForceLeaveOptions(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
// Eject somebody with token
|
|
|
|
err := agent.ForceLeaveOptions(s.Config.NodeName, ForceLeaveOpts{Prune: true}, &QueryOptions{Token: "testToken"})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 21:05:02 +00:00
|
|
|
func TestAPI_AgentMonitor(t *testing.T) {
|
2016-11-16 21:45:26 +00:00
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
2020-01-28 23:50:41 +00:00
|
|
|
logCh, err := agent.Monitor("debug", nil, nil)
|
2016-11-16 21:45:26 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2020-04-01 07:47:57 +00:00
|
|
|
retry.Run(t, func(r *retry.R) {
|
|
|
|
{
|
|
|
|
// Register a service to be sure something happens in secs
|
|
|
|
serviceReg := &AgentServiceRegistration{
|
|
|
|
Name: "redis",
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(serviceReg); err != nil {
|
|
|
|
r.Fatalf("err: %v", err)
|
|
|
|
}
|
2016-11-16 21:45:26 +00:00
|
|
|
}
|
2020-04-01 07:47:57 +00:00
|
|
|
// Wait for the first log message and validate it
|
|
|
|
select {
|
|
|
|
case log := <-logCh:
|
|
|
|
if !(strings.Contains(log, "[INFO]") || strings.Contains(log, "[DEBUG]")) {
|
|
|
|
r.Fatalf("bad: %q", log)
|
|
|
|
}
|
|
|
|
case <-time.After(10 * time.Second):
|
|
|
|
r.Fatalf("failed to get a log message")
|
|
|
|
}
|
|
|
|
})
|
2016-11-16 21:45:26 +00:00
|
|
|
}
|
|
|
|
|
2020-01-28 23:50:41 +00:00
|
|
|
func TestAPI_AgentMonitorJSON(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
logCh, err := agent.MonitorJSON("debug", nil, nil)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2020-03-30 18:21:29 +00:00
|
|
|
retry.Run(t, func(r *retry.R) {
|
|
|
|
{
|
|
|
|
// Register a service to be sure something happens in secs
|
|
|
|
serviceReg := &AgentServiceRegistration{
|
|
|
|
Name: "redis",
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(serviceReg); err != nil {
|
|
|
|
r.Fatalf("err: %v", err)
|
|
|
|
}
|
2020-01-28 23:50:41 +00:00
|
|
|
}
|
2020-03-30 18:21:29 +00:00
|
|
|
// Wait for the first log message and validate it is valid JSON
|
|
|
|
select {
|
|
|
|
case log := <-logCh:
|
|
|
|
var output map[string]interface{}
|
|
|
|
if err := json.Unmarshal([]byte(log), &output); err != nil {
|
|
|
|
r.Fatalf("log output was not JSON: %q", log)
|
|
|
|
}
|
|
|
|
case <-time.After(10 * time.Second):
|
|
|
|
r.Fatalf("failed to get a log message")
|
|
|
|
}
|
|
|
|
})
|
2020-01-28 23:50:41 +00:00
|
|
|
}
|
|
|
|
|
2021-07-30 17:07:13 +00:00
|
|
|
func TestAPI_ServiceMaintenanceOpts(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-21 18:51:26 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-21 18:51:26 +00:00
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
// First register a service
|
|
|
|
serviceReg := &AgentServiceRegistration{
|
|
|
|
Name: "redis",
|
|
|
|
}
|
|
|
|
if err := agent.ServiceRegister(serviceReg); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2021-07-30 17:07:13 +00:00
|
|
|
// Specify namespace in query option
|
2022-08-31 21:15:32 +00:00
|
|
|
opts := &QueryOptions{Namespace: defaultNamespace}
|
2021-07-30 17:07:13 +00:00
|
|
|
|
2015-01-21 18:51:26 +00:00
|
|
|
// Enable maintenance mode
|
2021-07-30 17:07:13 +00:00
|
|
|
if err := agent.EnableServiceMaintenanceOpts("redis", "broken", opts); err != nil {
|
2015-01-21 18:51:26 +00:00
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure a critical check was added
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
found := false
|
|
|
|
for _, check := range checks {
|
2015-01-21 19:08:57 +00:00
|
|
|
if strings.Contains(check.CheckID, "maintenance") {
|
2015-01-21 18:51:26 +00:00
|
|
|
found = true
|
2016-04-23 23:01:59 +00:00
|
|
|
if check.Status != HealthCritical || check.Notes != "broken" {
|
2015-01-21 18:51:26 +00:00
|
|
|
t.Fatalf("bad: %#v", checks)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
t.Fatalf("bad: %#v", checks)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Disable maintenance mode
|
2021-07-30 17:07:13 +00:00
|
|
|
if err := agent.DisableServiceMaintenanceOpts("redis", opts); err != nil {
|
2015-01-21 18:51:26 +00:00
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the critical health check was removed
|
|
|
|
checks, err = agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
for _, check := range checks {
|
2015-01-21 19:08:57 +00:00
|
|
|
if strings.Contains(check.CheckID, "maintenance") {
|
|
|
|
t.Fatalf("should have removed health check")
|
|
|
|
}
|
2019-10-17 18:33:11 +00:00
|
|
|
if check.Type != "maintenance" {
|
|
|
|
t.Fatalf("expected type 'maintenance', got %s", check.Type)
|
|
|
|
}
|
2015-01-21 19:08:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-30 20:58:55 +00:00
|
|
|
func TestAPI_NodeMaintenance(t *testing.T) {
|
2015-05-08 17:27:24 +00:00
|
|
|
t.Parallel()
|
2015-01-21 19:08:57 +00:00
|
|
|
c, s := makeClient(t)
|
2015-03-03 02:18:38 +00:00
|
|
|
defer s.Stop()
|
2015-01-21 19:08:57 +00:00
|
|
|
|
|
|
|
agent := c.Agent()
|
2019-02-22 18:41:28 +00:00
|
|
|
s.WaitForSerfCheck(t)
|
2015-01-21 19:08:57 +00:00
|
|
|
|
|
|
|
// Enable maintenance mode
|
2015-01-21 21:02:47 +00:00
|
|
|
if err := agent.EnableNodeMaintenance("broken"); err != nil {
|
2015-01-21 19:08:57 +00:00
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that a critical check was added
|
|
|
|
checks, err := agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
found := false
|
|
|
|
for _, check := range checks {
|
|
|
|
if strings.Contains(check.CheckID, "maintenance") {
|
|
|
|
found = true
|
2016-04-23 23:01:59 +00:00
|
|
|
if check.Status != HealthCritical || check.Notes != "broken" {
|
2015-01-21 19:08:57 +00:00
|
|
|
t.Fatalf("bad: %#v", checks)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
t.Fatalf("bad: %#v", checks)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Disable maintenance mode
|
|
|
|
if err := agent.DisableNodeMaintenance(); err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure the check was removed
|
|
|
|
checks, err = agent.Checks()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
for _, check := range checks {
|
|
|
|
if strings.Contains(check.CheckID, "maintenance") {
|
2015-01-21 18:51:26 +00:00
|
|
|
t.Fatalf("should have removed health check")
|
|
|
|
}
|
2019-10-17 18:33:11 +00:00
|
|
|
if check.Type != "maintenance" {
|
|
|
|
t.Fatalf("expected type 'maintenance', got %s", check.Type)
|
|
|
|
}
|
2015-01-21 18:51:26 +00:00
|
|
|
}
|
|
|
|
}
|
2017-07-26 18:03:43 +00:00
|
|
|
|
|
|
|
func TestAPI_AgentUpdateToken(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeACLClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
t.Run("deprecated", func(t *testing.T) {
|
|
|
|
agent := c.Agent()
|
|
|
|
if _, err := agent.UpdateACLToken("root", nil); err != nil {
|
2023-01-27 15:17:07 +00:00
|
|
|
require.Contains(t, err.Error(), "Legacy ACL Tokens were deprecated in Consul 1.4")
|
2019-03-21 20:04:40 +00:00
|
|
|
}
|
2017-07-26 18:03:43 +00:00
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
if _, err := agent.UpdateACLAgentToken("root", nil); err != nil {
|
2023-01-27 15:17:07 +00:00
|
|
|
require.Contains(t, err.Error(), "Legacy ACL Tokens were deprecated in Consul 1.4")
|
2019-03-21 20:04:40 +00:00
|
|
|
}
|
2017-07-26 18:03:43 +00:00
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
if _, err := agent.UpdateACLAgentMasterToken("root", nil); err != nil {
|
2023-01-27 15:17:07 +00:00
|
|
|
require.Contains(t, err.Error(), "Legacy ACL Tokens were deprecated in Consul 1.4")
|
2019-03-21 20:04:40 +00:00
|
|
|
}
|
2017-07-26 18:03:43 +00:00
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
if _, err := agent.UpdateACLReplicationToken("root", nil); err != nil {
|
2023-01-27 15:17:07 +00:00
|
|
|
require.Contains(t, err.Error(), "Legacy ACL Tokens were deprecated in Consul 1.4")
|
2019-03-21 20:04:40 +00:00
|
|
|
}
|
|
|
|
})
|
2017-08-03 22:39:31 +00:00
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
t.Run("new with no fallback", func(t *testing.T) {
|
|
|
|
agent := c.Agent()
|
|
|
|
if _, err := agent.UpdateDefaultACLToken("root", nil); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2019-02-27 19:28:31 +00:00
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
if _, err := agent.UpdateAgentACLToken("root", nil); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2019-02-27 19:28:31 +00:00
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
if _, err := agent.UpdateAgentMasterACLToken("root", nil); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2019-02-27 19:28:31 +00:00
|
|
|
|
2021-12-02 17:05:27 +00:00
|
|
|
if _, err := agent.UpdateAgentRecoveryACLToken("root", nil); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
if _, err := agent.UpdateReplicationACLToken("root", nil); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2023-01-10 16:24:02 +00:00
|
|
|
|
|
|
|
if _, err := agent.UpdateConfigFileRegistrationToken("root", nil); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2023-09-20 21:50:06 +00:00
|
|
|
if _, err := agent.UpdateDNSToken("root", nil); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
})
|
2019-02-27 19:28:31 +00:00
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
t.Run("new with fallback", func(t *testing.T) {
|
|
|
|
// Respond with 404 for the new paths to trigger fallback.
|
|
|
|
failer := func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
w.WriteHeader(404)
|
|
|
|
}
|
|
|
|
notfound := httptest.NewServer(http.HandlerFunc(failer))
|
|
|
|
defer notfound.Close()
|
|
|
|
|
|
|
|
raw := c // real consul client
|
|
|
|
|
|
|
|
// Set up a reverse proxy that will send some requests to the
|
|
|
|
// 404 server and pass everything else through to the real Consul
|
|
|
|
// server.
|
|
|
|
director := func(req *http.Request) {
|
|
|
|
req.URL.Scheme = "http"
|
|
|
|
|
|
|
|
switch req.URL.Path {
|
|
|
|
case "/v1/agent/token/default",
|
|
|
|
"/v1/agent/token/agent",
|
|
|
|
"/v1/agent/token/agent_master",
|
|
|
|
"/v1/agent/token/replication":
|
|
|
|
req.URL.Host = notfound.URL[7:] // Strip off "http://".
|
|
|
|
default:
|
|
|
|
req.URL.Host = raw.config.Address
|
|
|
|
}
|
|
|
|
}
|
|
|
|
proxy := httptest.NewServer(&httputil.ReverseProxy{Director: director})
|
|
|
|
defer proxy.Close()
|
|
|
|
|
|
|
|
// Make another client that points at the proxy instead of the real
|
|
|
|
// Consul server.
|
|
|
|
config := raw.config
|
|
|
|
config.Address = proxy.URL[7:] // Strip off "http://".
|
|
|
|
c, err := NewClient(&config)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
_, err = agent.UpdateDefaultACLToken("root", nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
_, err = agent.UpdateAgentACLToken("root", nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
_, err = agent.UpdateAgentMasterACLToken("root", nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-12-02 17:05:27 +00:00
|
|
|
_, err = agent.UpdateAgentRecoveryACLToken("root", nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2019-03-21 20:04:40 +00:00
|
|
|
_, err = agent.UpdateReplicationACLToken("root", nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("new with 403s", func(t *testing.T) {
|
|
|
|
failer := func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
w.WriteHeader(403)
|
|
|
|
}
|
|
|
|
authdeny := httptest.NewServer(http.HandlerFunc(failer))
|
|
|
|
defer authdeny.Close()
|
|
|
|
|
|
|
|
raw := c // real consul client
|
|
|
|
|
|
|
|
// Make another client that points at the proxy instead of the real
|
|
|
|
// Consul server.
|
|
|
|
config := raw.config
|
|
|
|
config.Address = authdeny.URL[7:] // Strip off "http://".
|
|
|
|
c, err := NewClient(&config)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
_, err = agent.UpdateDefaultACLToken("root", nil)
|
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
_, err = agent.UpdateAgentACLToken("root", nil)
|
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
_, err = agent.UpdateAgentMasterACLToken("root", nil)
|
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
_, err = agent.UpdateReplicationACLToken("root", nil)
|
|
|
|
require.Error(t, err)
|
2023-01-10 16:24:02 +00:00
|
|
|
|
|
|
|
_, err = agent.UpdateConfigFileRegistrationToken("root", nil)
|
|
|
|
require.Error(t, err)
|
2023-09-20 21:50:06 +00:00
|
|
|
|
|
|
|
_, err = agent.UpdateDNSToken("root", nil)
|
|
|
|
require.Error(t, err)
|
2019-03-21 20:04:40 +00:00
|
|
|
})
|
2017-07-26 18:03:43 +00:00
|
|
|
}
|
2018-03-27 23:50:17 +00:00
|
|
|
|
|
|
|
func TestAPI_AgentConnectCARoots_empty(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2018-05-10 16:14:16 +00:00
|
|
|
c, s := makeClientWithConfig(t, nil, func(c *testutil.TestServerConfig) {
|
2022-11-09 17:29:55 +00:00
|
|
|
// Explicitly disable Connect to prevent CA being bootstrapped
|
|
|
|
c.Connect = map[string]interface{}{
|
|
|
|
"enabled": false,
|
|
|
|
}
|
2018-05-10 16:14:16 +00:00
|
|
|
})
|
2018-03-27 23:50:17 +00:00
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
2018-07-25 19:26:27 +00:00
|
|
|
_, _, err := agent.ConnectCARoots(nil)
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
require.Contains(t, err.Error(), "Connect must be enabled")
|
2018-03-27 23:50:17 +00:00
|
|
|
}
|
2018-04-05 11:53:42 +00:00
|
|
|
|
2018-04-26 13:01:20 +00:00
|
|
|
func TestAPI_AgentConnectCARoots_list(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2018-05-10 16:14:16 +00:00
|
|
|
c, s := makeClient(t)
|
2018-04-26 13:01:20 +00:00
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
Added SOA configuration for DNS settings. (#4714)
This will allow to fine TUNE SOA settings sent by Consul in DNS responses,
for instance to be able to control negative ttl.
Will fix: https://github.com/hashicorp/consul/issues/4713
# Example
Override all settings:
* min_ttl: 0 => 60s
* retry: 600 (10m) => 300s (5 minutes),
* expire: 86400 (24h) => 43200 (12h)
* refresh: 3600 (1h) => 1800 (30 minutes)
```
consul agent -dev -hcl 'dns_config={soa={min_ttl=60,retry=300,expire=43200,refresh=1800}}'
```
Result:
```
dig +multiline @localhost -p 8600 service.consul
; <<>> DiG 9.12.1 <<>> +multiline @localhost -p 8600 service.consul
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 36557
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;service.consul. IN A
;; AUTHORITY SECTION:
consul. 0 IN SOA ns.consul. hostmaster.consul. (
1537959133 ; serial
1800 ; refresh (30 minutes)
300 ; retry (5 minutes)
43200 ; expire (12 hours)
60 ; minimum (1 minute)
)
;; Query time: 4 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Wed Sep 26 12:52:13 CEST 2018
;; MSG SIZE rcvd: 93
```
2018-10-10 19:50:56 +00:00
|
|
|
s.WaitForSerfCheck(t)
|
2018-04-26 13:01:20 +00:00
|
|
|
list, meta, err := agent.ConnectCARoots(nil)
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.True(t, meta.LastIndex > 0)
|
|
|
|
require.Len(t, list.Roots, 1)
|
2018-04-26 13:01:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestAPI_AgentConnectCALeaf(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2018-05-10 16:14:16 +00:00
|
|
|
c, s := makeClient(t)
|
2018-04-26 13:01:20 +00:00
|
|
|
defer s.Stop()
|
|
|
|
|
2020-01-27 19:34:04 +00:00
|
|
|
// ensure we don't try to sign a leaf cert before connect has been initialized
|
|
|
|
s.WaitForActiveCARoot(t)
|
|
|
|
|
2018-04-26 13:01:20 +00:00
|
|
|
agent := c.Agent()
|
|
|
|
// Setup service
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: "foo",
|
|
|
|
Tags: []string{"bar", "baz"},
|
|
|
|
Port: 8000,
|
|
|
|
}
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NoError(t, agent.ServiceRegister(reg))
|
2018-04-26 13:01:20 +00:00
|
|
|
|
|
|
|
leaf, meta, err := agent.ConnectCALeaf("foo", nil)
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.True(t, meta.LastIndex > 0)
|
2018-04-26 13:01:20 +00:00
|
|
|
// Sanity checks here as we have actual certificate validation checks at many
|
|
|
|
// other levels.
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.NotEmpty(t, leaf.SerialNumber)
|
|
|
|
require.NotEmpty(t, leaf.CertPEM)
|
|
|
|
require.NotEmpty(t, leaf.PrivateKeyPEM)
|
|
|
|
require.Equal(t, "foo", leaf.Service)
|
|
|
|
require.True(t, strings.HasSuffix(leaf.ServiceURI, "/svc/foo"))
|
|
|
|
require.True(t, leaf.ModifyIndex > 0)
|
|
|
|
require.True(t, leaf.ValidAfter.Before(time.Now()))
|
|
|
|
require.True(t, leaf.ValidBefore.After(time.Now()))
|
2018-04-26 13:01:20 +00:00
|
|
|
}
|
|
|
|
|
2018-04-05 11:53:42 +00:00
|
|
|
func TestAPI_AgentConnectAuthorize(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
Added SOA configuration for DNS settings. (#4714)
This will allow to fine TUNE SOA settings sent by Consul in DNS responses,
for instance to be able to control negative ttl.
Will fix: https://github.com/hashicorp/consul/issues/4713
# Example
Override all settings:
* min_ttl: 0 => 60s
* retry: 600 (10m) => 300s (5 minutes),
* expire: 86400 (24h) => 43200 (12h)
* refresh: 3600 (1h) => 1800 (30 minutes)
```
consul agent -dev -hcl 'dns_config={soa={min_ttl=60,retry=300,expire=43200,refresh=1800}}'
```
Result:
```
dig +multiline @localhost -p 8600 service.consul
; <<>> DiG 9.12.1 <<>> +multiline @localhost -p 8600 service.consul
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 36557
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;service.consul. IN A
;; AUTHORITY SECTION:
consul. 0 IN SOA ns.consul. hostmaster.consul. (
1537959133 ; serial
1800 ; refresh (30 minutes)
300 ; retry (5 minutes)
43200 ; expire (12 hours)
60 ; minimum (1 minute)
)
;; Query time: 4 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Wed Sep 26 12:52:13 CEST 2018
;; MSG SIZE rcvd: 93
```
2018-10-10 19:50:56 +00:00
|
|
|
s.WaitForSerfCheck(t)
|
2018-04-05 11:53:42 +00:00
|
|
|
params := &AgentAuthorizeParams{
|
|
|
|
Target: "foo",
|
|
|
|
ClientCertSerial: "fake",
|
|
|
|
// Importing connect.TestSpiffeIDService creates an import cycle
|
2018-05-10 16:04:33 +00:00
|
|
|
ClientCertURI: "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/ny1/svc/web",
|
2018-04-05 11:53:42 +00:00
|
|
|
}
|
|
|
|
auth, err := agent.ConnectAuthorize(params)
|
bulk rewrite using this script
set -euo pipefail
unset CDPATH
cd "$(dirname "$0")"
for f in $(git grep '\brequire := require\.New(' | cut -d':' -f1 | sort -u); do
echo "=== require: $f ==="
sed -i '/require := require.New(t)/d' $f
# require.XXX(blah) but not require.XXX(tblah) or require.XXX(rblah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\([^tr]\)/require.\1(t,\2/g' $f
# require.XXX(tblah) but not require.XXX(t, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/require.\1(t,\2/g' $f
# require.XXX(rblah) but not require.XXX(r, blah)
sed -i 's/\brequire\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/require.\1(t,\2/g' $f
gofmt -s -w $f
done
for f in $(git grep '\bassert := assert\.New(' | cut -d':' -f1 | sort -u); do
echo "=== assert: $f ==="
sed -i '/assert := assert.New(t)/d' $f
# assert.XXX(blah) but not assert.XXX(tblah) or assert.XXX(rblah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\([^tr]\)/assert.\1(t,\2/g' $f
# assert.XXX(tblah) but not assert.XXX(t, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(t[^,]\)/assert.\1(t,\2/g' $f
# assert.XXX(rblah) but not assert.XXX(r, blah)
sed -i 's/\bassert\.\([a-zA-Z0-9_]*\)(\(r[^,]\)/assert.\1(t,\2/g' $f
gofmt -s -w $f
done
2022-01-20 16:46:23 +00:00
|
|
|
require.Nil(t, err)
|
|
|
|
require.True(t, auth.Authorized)
|
|
|
|
require.Equal(t, auth.Reason, "Default behavior configured by ACLs")
|
2018-04-05 11:53:42 +00:00
|
|
|
}
|
2018-04-20 13:24:24 +00:00
|
|
|
|
2021-07-30 17:07:13 +00:00
|
|
|
func TestAPI_AgentHealthServiceOpts(t *testing.T) {
|
2019-01-07 14:39:23 +00:00
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
requireServiceHealthID := func(t *testing.T, serviceID, expected string, shouldExist bool) {
|
|
|
|
msg := fmt.Sprintf("service id:%s, shouldExist:%v, expectedStatus:%s : bad %%s", serviceID, shouldExist, expected)
|
|
|
|
|
2022-08-31 21:15:32 +00:00
|
|
|
opts := &QueryOptions{Namespace: defaultNamespace}
|
2021-07-30 17:07:13 +00:00
|
|
|
state, out, err := agent.AgentHealthServiceByIDOpts(serviceID, opts)
|
2019-01-07 14:39:23 +00:00
|
|
|
require.Nil(t, err, msg, "err")
|
|
|
|
require.Equal(t, expected, state, msg, "state")
|
|
|
|
if !shouldExist {
|
|
|
|
require.Nil(t, out, msg, "shouldExist")
|
|
|
|
} else {
|
|
|
|
require.NotNil(t, out, msg, "output")
|
|
|
|
require.Equal(t, serviceID, out.Service.ID, msg, "output")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
requireServiceHealthName := func(t *testing.T, serviceName, expected string, shouldExist bool) {
|
|
|
|
msg := fmt.Sprintf("service name:%s, shouldExist:%v, expectedStatus:%s : bad %%s", serviceName, shouldExist, expected)
|
|
|
|
|
2022-08-31 21:15:32 +00:00
|
|
|
opts := &QueryOptions{Namespace: defaultNamespace}
|
2021-07-30 17:07:13 +00:00
|
|
|
state, outs, err := agent.AgentHealthServiceByNameOpts(serviceName, opts)
|
2019-01-07 14:39:23 +00:00
|
|
|
require.Nil(t, err, msg, "err")
|
|
|
|
require.Equal(t, expected, state, msg, "state")
|
|
|
|
if !shouldExist {
|
|
|
|
require.Equal(t, 0, len(outs), msg, "output")
|
|
|
|
} else {
|
|
|
|
require.True(t, len(outs) > 0, msg, "output")
|
|
|
|
for _, o := range outs {
|
|
|
|
require.Equal(t, serviceName, o.Service.Service, msg, "output")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
requireServiceHealthID(t, "_i_do_not_exist_", HealthCritical, false)
|
|
|
|
requireServiceHealthName(t, "_i_do_not_exist_", HealthCritical, false)
|
|
|
|
|
|
|
|
testServiceID1 := "foo"
|
|
|
|
testServiceID2 := "foofoo"
|
|
|
|
testServiceName := "bar"
|
|
|
|
|
|
|
|
// register service
|
|
|
|
reg := &AgentServiceRegistration{
|
|
|
|
Name: testServiceName,
|
|
|
|
ID: testServiceID1,
|
|
|
|
Port: 8000,
|
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err := agent.ServiceRegister(reg)
|
|
|
|
require.Nil(t, err)
|
|
|
|
requireServiceHealthID(t, testServiceID1, HealthCritical, true)
|
|
|
|
requireServiceHealthName(t, testServiceName, HealthCritical, true)
|
|
|
|
|
|
|
|
err = agent.WarnTTL(fmt.Sprintf("service:%s", testServiceID1), "I am warn")
|
|
|
|
require.Nil(t, err)
|
|
|
|
requireServiceHealthName(t, testServiceName, HealthWarning, true)
|
|
|
|
requireServiceHealthID(t, testServiceID1, HealthWarning, true)
|
|
|
|
|
|
|
|
err = agent.PassTTL(fmt.Sprintf("service:%s", testServiceID1), "I am good :)")
|
|
|
|
require.Nil(t, err)
|
|
|
|
requireServiceHealthName(t, testServiceName, HealthPassing, true)
|
|
|
|
requireServiceHealthID(t, testServiceID1, HealthPassing, true)
|
|
|
|
|
|
|
|
err = agent.FailTTL(fmt.Sprintf("service:%s", testServiceID1), "I am dead.")
|
|
|
|
require.Nil(t, err)
|
|
|
|
requireServiceHealthName(t, testServiceName, HealthCritical, true)
|
|
|
|
requireServiceHealthID(t, testServiceID1, HealthCritical, true)
|
|
|
|
|
|
|
|
// register another service
|
|
|
|
reg = &AgentServiceRegistration{
|
|
|
|
Name: testServiceName,
|
|
|
|
ID: testServiceID2,
|
|
|
|
Port: 8000,
|
|
|
|
Check: &AgentServiceCheck{
|
|
|
|
TTL: "15s",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
err = agent.ServiceRegister(reg)
|
|
|
|
require.Nil(t, err)
|
|
|
|
requireServiceHealthName(t, testServiceName, HealthCritical, true)
|
|
|
|
|
|
|
|
err = agent.PassTTL(fmt.Sprintf("service:%s", testServiceID1), "I am good :)")
|
|
|
|
require.Nil(t, err)
|
|
|
|
requireServiceHealthName(t, testServiceName, HealthCritical, true)
|
|
|
|
|
|
|
|
err = agent.WarnTTL(fmt.Sprintf("service:%s", testServiceID2), "I am warn")
|
|
|
|
require.Nil(t, err)
|
|
|
|
requireServiceHealthName(t, testServiceName, HealthWarning, true)
|
|
|
|
|
|
|
|
err = agent.PassTTL(fmt.Sprintf("service:%s", testServiceID2), "I am good :)")
|
|
|
|
require.Nil(t, err)
|
|
|
|
requireServiceHealthName(t, testServiceName, HealthPassing, true)
|
|
|
|
}
|
2019-06-17 14:51:50 +00:00
|
|
|
|
|
|
|
func TestAgentService_JSON_OmitTaggedAdddresses(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
cases := []struct {
|
|
|
|
name string
|
|
|
|
as AgentService
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"nil",
|
|
|
|
AgentService{
|
|
|
|
TaggedAddresses: nil,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"empty",
|
|
|
|
AgentService{
|
|
|
|
TaggedAddresses: make(map[string]ServiceAddress),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
name := tc.name
|
|
|
|
as := tc.as
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
data, err := json.Marshal(as)
|
|
|
|
require.NoError(t, err)
|
|
|
|
var raw map[string]interface{}
|
|
|
|
err = json.Unmarshal(data, &raw)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotContains(t, raw, "TaggedAddresses")
|
|
|
|
require.NotContains(t, raw, "tagged_addresses")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2019-06-18 00:52:01 +00:00
|
|
|
|
|
|
|
func TestAgentService_Register_MeshGateway(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg := AgentServiceRegistration{
|
|
|
|
Kind: ServiceKindMeshGateway,
|
|
|
|
Name: "mesh-gateway",
|
|
|
|
Address: "10.1.2.3",
|
|
|
|
Port: 8443,
|
|
|
|
Proxy: &AgentServiceConnectProxyConfig{
|
|
|
|
Config: map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
err := agent.ServiceRegister(®)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
svc, _, err := agent.Service("mesh-gateway", nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, svc)
|
|
|
|
require.Equal(t, ServiceKindMeshGateway, svc.Kind)
|
|
|
|
require.NotNil(t, svc.Proxy)
|
|
|
|
require.Contains(t, svc.Proxy.Config, "foo")
|
2020-03-26 16:20:56 +00:00
|
|
|
require.Equal(t, "bar", svc.Proxy.Config["foo"])
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAgentService_Register_TerminatingGateway(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
reg := AgentServiceRegistration{
|
|
|
|
Kind: ServiceKindTerminatingGateway,
|
|
|
|
Name: "terminating-gateway",
|
|
|
|
Address: "10.1.2.3",
|
|
|
|
Port: 8443,
|
|
|
|
Proxy: &AgentServiceConnectProxyConfig{
|
|
|
|
Config: map[string]interface{}{
|
|
|
|
"foo": "bar",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
err := agent.ServiceRegister(®)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
svc, _, err := agent.Service("terminating-gateway", nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, svc)
|
|
|
|
require.Equal(t, ServiceKindTerminatingGateway, svc.Kind)
|
|
|
|
require.NotNil(t, svc.Proxy)
|
|
|
|
require.Contains(t, svc.Proxy.Config, "foo")
|
2019-06-18 00:52:01 +00:00
|
|
|
require.Equal(t, "bar", svc.Proxy.Config["foo"])
|
|
|
|
}
|
2019-09-26 02:55:52 +00:00
|
|
|
|
|
|
|
func TestAgentService_ExposeChecks(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
c, s := makeClient(t)
|
|
|
|
defer s.Stop()
|
|
|
|
|
|
|
|
agent := c.Agent()
|
|
|
|
|
|
|
|
path := ExposePath{
|
|
|
|
LocalPathPort: 8080,
|
|
|
|
ListenerPort: 21500,
|
|
|
|
Path: "/metrics",
|
|
|
|
Protocol: "http2",
|
|
|
|
}
|
|
|
|
reg := AgentServiceRegistration{
|
|
|
|
Kind: ServiceKindConnectProxy,
|
|
|
|
Name: "expose-proxy",
|
|
|
|
Address: "10.1.2.3",
|
|
|
|
Port: 8443,
|
|
|
|
Proxy: &AgentServiceConnectProxyConfig{
|
|
|
|
DestinationServiceName: "expose",
|
|
|
|
Expose: ExposeConfig{
|
|
|
|
Checks: true,
|
|
|
|
Paths: []ExposePath{
|
|
|
|
path,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
err := agent.ServiceRegister(®)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
svc, _, err := agent.Service("expose-proxy", nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, svc)
|
|
|
|
require.Equal(t, ServiceKindConnectProxy, svc.Kind)
|
|
|
|
require.NotNil(t, svc.Proxy)
|
|
|
|
require.Len(t, svc.Proxy.Expose.Paths, 1)
|
|
|
|
require.True(t, svc.Proxy.Expose.Checks)
|
|
|
|
require.Equal(t, path, svc.Proxy.Expose.Paths[0])
|
|
|
|
}
|
2020-08-27 15:00:48 +00:00
|
|
|
|
|
|
|
func TestMemberACLMode(t *testing.T) {
|
|
|
|
type testCase struct {
|
|
|
|
tagValue string
|
|
|
|
expectedMode MemberACLMode
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := map[string]testCase{
|
|
|
|
"disabled": {
|
|
|
|
tagValue: "0",
|
|
|
|
expectedMode: ACLModeDisabled,
|
|
|
|
},
|
|
|
|
"enabled": {
|
|
|
|
tagValue: "1",
|
|
|
|
expectedMode: ACLModeEnabled,
|
|
|
|
},
|
|
|
|
"legacy": {
|
|
|
|
tagValue: "2",
|
2023-02-06 15:35:52 +00:00
|
|
|
expectedMode: ACLModeUnknown,
|
2020-08-27 15:00:48 +00:00
|
|
|
},
|
|
|
|
"unknown-3": {
|
|
|
|
tagValue: "3",
|
|
|
|
expectedMode: ACLModeUnknown,
|
|
|
|
},
|
|
|
|
"unknown-other": {
|
|
|
|
tagValue: "77",
|
|
|
|
expectedMode: ACLModeUnknown,
|
|
|
|
},
|
|
|
|
"unknown-not-present": {
|
|
|
|
tagValue: "",
|
|
|
|
expectedMode: ACLModeUnknown,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, tcase := range cases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
tags := map[string]string{}
|
|
|
|
|
|
|
|
if tcase.tagValue != "" {
|
|
|
|
tags[MemberTagKeyACLMode] = tcase.tagValue
|
|
|
|
}
|
|
|
|
|
|
|
|
m := AgentMember{
|
|
|
|
Tags: tags,
|
|
|
|
}
|
|
|
|
|
|
|
|
require.Equal(t, tcase.expectedMode, m.ACLMode())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMemberIsConsulServer(t *testing.T) {
|
|
|
|
type testCase struct {
|
|
|
|
tagValue string
|
|
|
|
isServer bool
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := map[string]testCase{
|
|
|
|
"not-present": {
|
|
|
|
tagValue: "",
|
|
|
|
isServer: false,
|
|
|
|
},
|
|
|
|
"server": {
|
|
|
|
tagValue: MemberTagValueRoleServer,
|
|
|
|
isServer: true,
|
|
|
|
},
|
|
|
|
"client": {
|
|
|
|
tagValue: "client",
|
|
|
|
isServer: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, tcase := range cases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
tags := map[string]string{}
|
|
|
|
|
|
|
|
if tcase.tagValue != "" {
|
|
|
|
tags[MemberTagKeyRole] = tcase.tagValue
|
|
|
|
}
|
|
|
|
|
|
|
|
m := AgentMember{
|
|
|
|
Tags: tags,
|
|
|
|
}
|
|
|
|
|
|
|
|
require.Equal(t, tcase.isServer, m.IsConsulServer())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|