mirror of https://github.com/status-im/consul.git
dns token (#17936)
* dns token fix whitespace for docs and comments fix test cases fix test cases remove tabs in help text Add changelog Peering dns test Peering dns test Partial implementation of Peered DNS test Swap to new topology lib expose dns port for integration tests on client remove partial test implementation remove extra port exposure remove changelog from the ent pr Add dns token to set-agent-token switch Add enterprise golden file Use builtin/dns template in tests Update ent dns policy Update ent dns template test remove local gen certs fix templated policy specs * add changelog * go mod tidy
This commit is contained in:
parent
0236c48369
commit
9eaa8eb026
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:feature
|
||||||
|
acl: Add new `acl.tokens.dns` config field which specifies the token used implicitly during dns checks.
|
||||||
|
```
|
|
@ -1531,6 +1531,9 @@ func (s *HTTPHandlers) AgentToken(resp http.ResponseWriter, req *http.Request) (
|
||||||
case "config_file_service_registration":
|
case "config_file_service_registration":
|
||||||
s.agent.tokens.UpdateConfigFileRegistrationToken(args.Token, token_store.TokenSourceAPI)
|
s.agent.tokens.UpdateConfigFileRegistrationToken(args.Token, token_store.TokenSourceAPI)
|
||||||
|
|
||||||
|
case "dns_token", "dns":
|
||||||
|
s.agent.tokens.UpdateDNSToken(args.Token, token_store.TokenSourceAPI)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return HTTPError{StatusCode: http.StatusNotFound, Reason: fmt.Sprintf("Token %q is unknown", target)}
|
return HTTPError{StatusCode: http.StatusNotFound, Reason: fmt.Sprintf("Token %q is unknown", target)}
|
||||||
}
|
}
|
||||||
|
|
|
@ -882,6 +882,7 @@ func (b *builder) build() (rt RuntimeConfig, err error) {
|
||||||
ACLAgentRecoveryToken: stringVal(c.ACL.Tokens.AgentRecovery),
|
ACLAgentRecoveryToken: stringVal(c.ACL.Tokens.AgentRecovery),
|
||||||
ACLReplicationToken: stringVal(c.ACL.Tokens.Replication),
|
ACLReplicationToken: stringVal(c.ACL.Tokens.Replication),
|
||||||
ACLConfigFileRegistrationToken: stringVal(c.ACL.Tokens.ConfigFileRegistration),
|
ACLConfigFileRegistrationToken: stringVal(c.ACL.Tokens.ConfigFileRegistration),
|
||||||
|
ACLDNSToken: stringVal(c.ACL.Tokens.DNS),
|
||||||
},
|
},
|
||||||
|
|
||||||
// Autopilot
|
// Autopilot
|
||||||
|
|
|
@ -778,6 +778,7 @@ type Tokens struct {
|
||||||
Default *string `mapstructure:"default"`
|
Default *string `mapstructure:"default"`
|
||||||
Agent *string `mapstructure:"agent"`
|
Agent *string `mapstructure:"agent"`
|
||||||
ConfigFileRegistration *string `mapstructure:"config_file_service_registration"`
|
ConfigFileRegistration *string `mapstructure:"config_file_service_registration"`
|
||||||
|
DNS *string `mapstructure:"dns"`
|
||||||
|
|
||||||
// Enterprise Only
|
// Enterprise Only
|
||||||
ManagedServiceProvider []ServiceProviderToken `mapstructure:"managed_service_provider"`
|
ManagedServiceProvider []ServiceProviderToken `mapstructure:"managed_service_provider"`
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
"ACLAgentRecoveryToken": "hidden",
|
"ACLAgentRecoveryToken": "hidden",
|
||||||
"ACLAgentToken": "hidden",
|
"ACLAgentToken": "hidden",
|
||||||
"ACLConfigFileRegistrationToken": "hidden",
|
"ACLConfigFileRegistrationToken": "hidden",
|
||||||
|
"ACLDNSToken": "hidden",
|
||||||
"ACLDefaultToken": "hidden",
|
"ACLDefaultToken": "hidden",
|
||||||
"ACLReplicationToken": "hidden",
|
"ACLReplicationToken": "hidden",
|
||||||
"DataDir": "",
|
"DataDir": "",
|
||||||
|
|
22
agent/dns.go
22
agent/dns.go
|
@ -416,7 +416,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) {
|
||||||
args := structs.DCSpecificRequest{
|
args := structs.DCSpecificRequest{
|
||||||
Datacenter: datacenter,
|
Datacenter: datacenter,
|
||||||
QueryOptions: structs.QueryOptions{
|
QueryOptions: structs.QueryOptions{
|
||||||
Token: d.agent.tokens.UserToken(),
|
Token: d.coalesceDNSToken(),
|
||||||
AllowStale: cfg.AllowStale,
|
AllowStale: cfg.AllowStale,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -452,7 +452,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) {
|
||||||
sargs := structs.ServiceSpecificRequest{
|
sargs := structs.ServiceSpecificRequest{
|
||||||
Datacenter: datacenter,
|
Datacenter: datacenter,
|
||||||
QueryOptions: structs.QueryOptions{
|
QueryOptions: structs.QueryOptions{
|
||||||
Token: d.agent.tokens.UserToken(),
|
Token: d.coalesceDNSToken(),
|
||||||
AllowStale: cfg.AllowStale,
|
AllowStale: cfg.AllowStale,
|
||||||
},
|
},
|
||||||
ServiceAddress: serviceAddress,
|
ServiceAddress: serviceAddress,
|
||||||
|
@ -513,7 +513,7 @@ func (d *DNSServer) handleQuery(resp dns.ResponseWriter, req *dns.Msg) {
|
||||||
|
|
||||||
cfg := d.config.Load().(*dnsConfig)
|
cfg := d.config.Load().(*dnsConfig)
|
||||||
|
|
||||||
// Setup the message response
|
// Set up the message response
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetReply(req)
|
m.SetReply(req)
|
||||||
m.Compress = !cfg.DisableCompression
|
m.Compress = !cfg.DisableCompression
|
||||||
|
@ -875,7 +875,7 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi
|
||||||
ServiceName: queryParts[len(queryParts)-1],
|
ServiceName: queryParts[len(queryParts)-1],
|
||||||
EnterpriseMeta: locality.EnterpriseMeta,
|
EnterpriseMeta: locality.EnterpriseMeta,
|
||||||
QueryOptions: structs.QueryOptions{
|
QueryOptions: structs.QueryOptions{
|
||||||
Token: d.agent.tokens.UserToken(),
|
Token: d.coalesceDNSToken(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if args.PeerName == "" {
|
if args.PeerName == "" {
|
||||||
|
@ -1093,7 +1093,7 @@ func (d *DNSServer) nodeLookup(cfg *dnsConfig, lookup nodeLookup, req, resp *dns
|
||||||
PeerName: lookup.PeerName,
|
PeerName: lookup.PeerName,
|
||||||
Node: lookup.Node,
|
Node: lookup.Node,
|
||||||
QueryOptions: structs.QueryOptions{
|
QueryOptions: structs.QueryOptions{
|
||||||
Token: d.agent.tokens.UserToken(),
|
Token: d.coalesceDNSToken(),
|
||||||
AllowStale: cfg.AllowStale,
|
AllowStale: cfg.AllowStale,
|
||||||
},
|
},
|
||||||
EnterpriseMeta: lookup.EnterpriseMeta,
|
EnterpriseMeta: lookup.EnterpriseMeta,
|
||||||
|
@ -1425,7 +1425,7 @@ func (d *DNSServer) lookupServiceNodes(cfg *dnsConfig, lookup serviceLookup) (st
|
||||||
ServiceTags: serviceTags,
|
ServiceTags: serviceTags,
|
||||||
TagFilter: lookup.Tag != "",
|
TagFilter: lookup.Tag != "",
|
||||||
QueryOptions: structs.QueryOptions{
|
QueryOptions: structs.QueryOptions{
|
||||||
Token: d.agent.tokens.UserToken(),
|
Token: d.coalesceDNSToken(),
|
||||||
AllowStale: cfg.AllowStale,
|
AllowStale: cfg.AllowStale,
|
||||||
MaxAge: cfg.CacheMaxAge,
|
MaxAge: cfg.CacheMaxAge,
|
||||||
UseCache: cfg.UseCache,
|
UseCache: cfg.UseCache,
|
||||||
|
@ -1503,7 +1503,7 @@ func (d *DNSServer) preparedQueryLookup(cfg *dnsConfig, datacenter, query string
|
||||||
Datacenter: datacenter,
|
Datacenter: datacenter,
|
||||||
QueryIDOrName: query,
|
QueryIDOrName: query,
|
||||||
QueryOptions: structs.QueryOptions{
|
QueryOptions: structs.QueryOptions{
|
||||||
Token: d.agent.tokens.UserToken(),
|
Token: d.coalesceDNSToken(),
|
||||||
AllowStale: cfg.AllowStale,
|
AllowStale: cfg.AllowStale,
|
||||||
MaxAge: cfg.CacheMaxAge,
|
MaxAge: cfg.CacheMaxAge,
|
||||||
},
|
},
|
||||||
|
@ -2172,3 +2172,11 @@ func (d *DNSServer) resolveCNAME(cfg *dnsConfig, name string, maxRecursionLevel
|
||||||
d.logger.Error("all resolvers failed for name", "name", name)
|
d.logger.Error("all resolvers failed for name", "name", name)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *DNSServer) coalesceDNSToken() string {
|
||||||
|
if d.agent.tokens.DNSToken() != "" {
|
||||||
|
return d.agent.tokens.DNSToken()
|
||||||
|
} else {
|
||||||
|
return d.agent.tokens.UserToken()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,11 +10,12 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/miekg/dns"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/acl"
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/testrpc"
|
"github.com/hashicorp/consul/testrpc"
|
||||||
"github.com/miekg/dns"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDNS_CE_PeeredServices(t *testing.T) {
|
func TestDNS_CE_PeeredServices(t *testing.T) {
|
||||||
|
|
|
@ -6310,6 +6310,22 @@ func TestDNS_ServiceLookup_SRV_RFC_TCP_Default(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initDNSToken(t *testing.T, rpc RPC) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
reqToken := structs.ACLTokenSetRequest{
|
||||||
|
Datacenter: "dc1",
|
||||||
|
ACLToken: structs.ACLToken{
|
||||||
|
SecretID: "279d4735-f8ca-4d48-b5cc-c00a9713bbf8",
|
||||||
|
Policies: nil,
|
||||||
|
TemplatedPolicies: []*structs.ACLTemplatedPolicy{{TemplateName: "builtin/dns"}},
|
||||||
|
},
|
||||||
|
WriteRequest: structs.WriteRequest{Token: "root"},
|
||||||
|
}
|
||||||
|
err := rpc.RPC(context.Background(), "ACL.TokenSet", &reqToken, &structs.ACLToken{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
|
func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("too slow for testing.Short")
|
t.Skip("too slow for testing.Short")
|
||||||
|
@ -6322,10 +6338,11 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{"root", 1},
|
{"root", 1},
|
||||||
{"anonymous", 0},
|
{"anonymous", 0},
|
||||||
|
{"dns", 1},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run("ACLToken == "+tt.token, func(t *testing.T) {
|
t.Run("ACLToken == "+tt.token, func(t *testing.T) {
|
||||||
a := NewTestAgent(t, `
|
hcl := `
|
||||||
primary_datacenter = "dc1"
|
primary_datacenter = "dc1"
|
||||||
|
|
||||||
acl {
|
acl {
|
||||||
|
@ -6335,13 +6352,34 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
|
||||||
|
|
||||||
tokens {
|
tokens {
|
||||||
initial_management = "root"
|
initial_management = "root"
|
||||||
default = "`+tt.token+`"
|
`
|
||||||
|
if tt.token == "dns" {
|
||||||
|
// Create a UUID for dns token since it doesn't have an alias
|
||||||
|
dnsToken := "279d4735-f8ca-4d48-b5cc-c00a9713bbf8"
|
||||||
|
|
||||||
|
hcl = hcl + `
|
||||||
|
default = "anonymous"
|
||||||
|
dns = "` + dnsToken + `"
|
||||||
|
`
|
||||||
|
} else {
|
||||||
|
hcl = hcl + `
|
||||||
|
default = "` + tt.token + `"
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
hcl = hcl + `
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`)
|
`
|
||||||
|
|
||||||
|
a := NewTestAgent(t, hcl)
|
||||||
defer a.Shutdown()
|
defer a.Shutdown()
|
||||||
testrpc.WaitForLeader(t, a.RPC, "dc1")
|
testrpc.WaitForLeader(t, a.RPC, "dc1")
|
||||||
|
|
||||||
|
if tt.token == "dns" {
|
||||||
|
initDNSToken(t, a)
|
||||||
|
}
|
||||||
|
|
||||||
// Register a service
|
// Register a service
|
||||||
args := &structs.RegisterRequest{
|
args := &structs.RegisterRequest{
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
|
@ -6373,6 +6411,7 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDNS_ServiceLookup_MetaTXT(t *testing.T) {
|
func TestDNS_ServiceLookup_MetaTXT(t *testing.T) {
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("too slow for testing.Short")
|
t.Skip("too slow for testing.Short")
|
||||||
|
|
|
@ -529,6 +529,7 @@ type TestACLConfigParams struct {
|
||||||
DefaultToken string
|
DefaultToken string
|
||||||
AgentRecoveryToken string
|
AgentRecoveryToken string
|
||||||
ReplicationToken string
|
ReplicationToken string
|
||||||
|
DNSToken string
|
||||||
EnableTokenReplication bool
|
EnableTokenReplication bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,7 +548,8 @@ func (p *TestACLConfigParams) HasConfiguredTokens() bool {
|
||||||
p.AgentToken != "" ||
|
p.AgentToken != "" ||
|
||||||
p.DefaultToken != "" ||
|
p.DefaultToken != "" ||
|
||||||
p.AgentRecoveryToken != "" ||
|
p.AgentRecoveryToken != "" ||
|
||||||
p.ReplicationToken != ""
|
p.ReplicationToken != "" ||
|
||||||
|
p.DNSToken != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestACLConfigNew() string {
|
func TestACLConfigNew() string {
|
||||||
|
@ -557,6 +559,7 @@ func TestACLConfigNew() string {
|
||||||
InitialManagementToken: "root",
|
InitialManagementToken: "root",
|
||||||
AgentToken: "root",
|
AgentToken: "root",
|
||||||
AgentRecoveryToken: "towel",
|
AgentRecoveryToken: "towel",
|
||||||
|
DNSToken: "dns",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ type Config struct {
|
||||||
ACLAgentRecoveryToken string
|
ACLAgentRecoveryToken string
|
||||||
ACLReplicationToken string
|
ACLReplicationToken string
|
||||||
ACLConfigFileRegistrationToken string
|
ACLConfigFileRegistrationToken string
|
||||||
|
ACLDNSToken string
|
||||||
|
|
||||||
EnterpriseConfig
|
EnterpriseConfig
|
||||||
}
|
}
|
||||||
|
@ -77,6 +78,7 @@ type persistedTokens struct {
|
||||||
Default string `json:"default,omitempty"`
|
Default string `json:"default,omitempty"`
|
||||||
Agent string `json:"agent,omitempty"`
|
Agent string `json:"agent,omitempty"`
|
||||||
ConfigFileRegistration string `json:"config_file_service_registration,omitempty"`
|
ConfigFileRegistration string `json:"config_file_service_registration,omitempty"`
|
||||||
|
DNS string `json:"dns,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type fileStore struct {
|
type fileStore struct {
|
||||||
|
@ -144,6 +146,16 @@ func loadTokens(s *Store, cfg Config, tokens persistedTokens, logger Logger) {
|
||||||
s.UpdateConfigFileRegistrationToken(cfg.ACLConfigFileRegistrationToken, TokenSourceConfig)
|
s.UpdateConfigFileRegistrationToken(cfg.ACLConfigFileRegistrationToken, TokenSourceConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tokens.DNS != "" {
|
||||||
|
s.UpdateDNSToken(tokens.DNS, TokenSourceAPI)
|
||||||
|
|
||||||
|
if cfg.ACLDNSToken != "" {
|
||||||
|
logger.Warn("\"dns\" token present in both the configuration and persisted token store, using the persisted token")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s.UpdateDNSToken(cfg.ACLDNSToken, TokenSourceConfig)
|
||||||
|
}
|
||||||
|
|
||||||
loadEnterpriseTokens(s, cfg)
|
loadEnterpriseTokens(s, cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +218,10 @@ func (p *fileStore) saveToFile(s *Store) error {
|
||||||
tokens.ConfigFileRegistration = tok
|
tokens.ConfigFileRegistration = tok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tok, source := s.DNSTokenAndSource(); tok != "" && source == TokenSourceAPI {
|
||||||
|
tokens.DNS = tok
|
||||||
|
}
|
||||||
|
|
||||||
data, err := json.Marshal(tokens)
|
data, err := json.Marshal(tokens)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.logger.Warn("failed to persist tokens", "error", err)
|
p.logger.Warn("failed to persist tokens", "error", err)
|
||||||
|
|
|
@ -8,9 +8,10 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/sdk/testutil"
|
|
||||||
"github.com/hashicorp/go-hclog"
|
"github.com/hashicorp/go-hclog"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/sdk/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestStore_Load(t *testing.T) {
|
func TestStore_Load(t *testing.T) {
|
||||||
|
@ -27,6 +28,7 @@ func TestStore_Load(t *testing.T) {
|
||||||
ACLDefaultToken: "charlie",
|
ACLDefaultToken: "charlie",
|
||||||
ACLReplicationToken: "delta",
|
ACLReplicationToken: "delta",
|
||||||
ACLConfigFileRegistrationToken: "echo",
|
ACLConfigFileRegistrationToken: "echo",
|
||||||
|
ACLDNSToken: "foxtrot",
|
||||||
}
|
}
|
||||||
require.NoError(t, store.Load(cfg, logger))
|
require.NoError(t, store.Load(cfg, logger))
|
||||||
require.Equal(t, "alfa", store.AgentToken())
|
require.Equal(t, "alfa", store.AgentToken())
|
||||||
|
@ -34,62 +36,69 @@ func TestStore_Load(t *testing.T) {
|
||||||
require.Equal(t, "charlie", store.UserToken())
|
require.Equal(t, "charlie", store.UserToken())
|
||||||
require.Equal(t, "delta", store.ReplicationToken())
|
require.Equal(t, "delta", store.ReplicationToken())
|
||||||
require.Equal(t, "echo", store.ConfigFileRegistrationToken())
|
require.Equal(t, "echo", store.ConfigFileRegistrationToken())
|
||||||
|
require.Equal(t, "foxtrot", store.DNSToken())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("updated from Config", func(t *testing.T) {
|
t.Run("updated from Config", func(t *testing.T) {
|
||||||
cfg := Config{
|
cfg := Config{
|
||||||
DataDir: dataDir,
|
DataDir: dataDir,
|
||||||
ACLDefaultToken: "echo",
|
ACLDefaultToken: "sierra",
|
||||||
ACLAgentToken: "foxtrot",
|
ACLAgentToken: "tango",
|
||||||
ACLAgentRecoveryToken: "golf",
|
ACLAgentRecoveryToken: "uniform",
|
||||||
ACLReplicationToken: "hotel",
|
ACLReplicationToken: "victor",
|
||||||
ACLConfigFileRegistrationToken: "india",
|
ACLConfigFileRegistrationToken: "xray",
|
||||||
|
ACLDNSToken: "zulu",
|
||||||
}
|
}
|
||||||
// ensures no error for missing persisted tokens file
|
// ensures no error for missing persisted tokens file
|
||||||
require.NoError(t, store.Load(cfg, logger))
|
require.NoError(t, store.Load(cfg, logger))
|
||||||
require.Equal(t, "echo", store.UserToken())
|
require.Equal(t, "sierra", store.UserToken())
|
||||||
require.Equal(t, "foxtrot", store.AgentToken())
|
require.Equal(t, "tango", store.AgentToken())
|
||||||
require.Equal(t, "golf", store.AgentRecoveryToken())
|
require.Equal(t, "uniform", store.AgentRecoveryToken())
|
||||||
require.Equal(t, "hotel", store.ReplicationToken())
|
require.Equal(t, "victor", store.ReplicationToken())
|
||||||
require.Equal(t, "india", store.ConfigFileRegistrationToken())
|
require.Equal(t, "xray", store.ConfigFileRegistrationToken())
|
||||||
|
require.Equal(t, "zulu", store.DNSToken())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("with persisted tokens", func(t *testing.T) {
|
t.Run("with persisted tokens", func(t *testing.T) {
|
||||||
cfg := Config{
|
cfg := Config{
|
||||||
DataDir: dataDir,
|
DataDir: dataDir,
|
||||||
ACLDefaultToken: "echo",
|
ACLDefaultToken: "alpha",
|
||||||
ACLAgentToken: "foxtrot",
|
ACLAgentToken: "bravo",
|
||||||
ACLAgentRecoveryToken: "golf",
|
ACLAgentRecoveryToken: "charlie",
|
||||||
ACLReplicationToken: "hotel",
|
ACLReplicationToken: "delta",
|
||||||
ACLConfigFileRegistrationToken: "delta",
|
ACLConfigFileRegistrationToken: "echo",
|
||||||
|
ACLDNSToken: "foxtrot",
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens := `{
|
tokens := `{
|
||||||
"agent" : "india",
|
"agent" : "golf",
|
||||||
"agent_recovery" : "juliett",
|
"agent_recovery" : "hotel",
|
||||||
"default": "kilo",
|
"default": "india",
|
||||||
"replication": "lima",
|
"replication": "juliet",
|
||||||
"config_file_service_registration": "mike"
|
"config_file_service_registration": "kilo",
|
||||||
|
"dns": "lima"
|
||||||
}`
|
}`
|
||||||
|
|
||||||
require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600))
|
require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600))
|
||||||
require.NoError(t, store.Load(cfg, logger))
|
require.NoError(t, store.Load(cfg, logger))
|
||||||
|
|
||||||
// no updates since token persistence is not enabled
|
// no updates since token persistence is not enabled
|
||||||
require.Equal(t, "echo", store.UserToken())
|
require.Equal(t, "alpha", store.UserToken())
|
||||||
require.Equal(t, "foxtrot", store.AgentToken())
|
require.Equal(t, "bravo", store.AgentToken())
|
||||||
require.Equal(t, "golf", store.AgentRecoveryToken())
|
require.Equal(t, "charlie", store.AgentRecoveryToken())
|
||||||
require.Equal(t, "hotel", store.ReplicationToken())
|
require.Equal(t, "delta", store.ReplicationToken())
|
||||||
require.Equal(t, "delta", store.ConfigFileRegistrationToken())
|
require.Equal(t, "echo", store.ConfigFileRegistrationToken())
|
||||||
|
require.Equal(t, "foxtrot", store.DNSToken())
|
||||||
|
|
||||||
cfg.EnablePersistence = true
|
cfg.EnablePersistence = true
|
||||||
require.NoError(t, store.Load(cfg, logger))
|
require.NoError(t, store.Load(cfg, logger))
|
||||||
|
|
||||||
require.Equal(t, "india", store.AgentToken())
|
require.Equal(t, "golf", store.AgentToken())
|
||||||
require.Equal(t, "juliett", store.AgentRecoveryToken())
|
require.Equal(t, "hotel", store.AgentRecoveryToken())
|
||||||
require.Equal(t, "kilo", store.UserToken())
|
require.Equal(t, "india", store.UserToken())
|
||||||
require.Equal(t, "lima", store.ReplicationToken())
|
require.Equal(t, "juliet", store.ReplicationToken())
|
||||||
require.Equal(t, "mike", store.ConfigFileRegistrationToken())
|
require.Equal(t, "kilo", store.ConfigFileRegistrationToken())
|
||||||
|
require.Equal(t, "lima", store.DNSToken())
|
||||||
|
|
||||||
// check store persistence was enabled
|
// check store persistence was enabled
|
||||||
require.NotNil(t, store.persistence)
|
require.NotNil(t, store.persistence)
|
||||||
|
@ -115,7 +124,8 @@ func TestStore_Load(t *testing.T) {
|
||||||
"agent_recovery" : "november",
|
"agent_recovery" : "november",
|
||||||
"default": "oscar",
|
"default": "oscar",
|
||||||
"replication" : "papa",
|
"replication" : "papa",
|
||||||
"config_file_service_registration" : "lima"
|
"config_file_service_registration" : "lima",
|
||||||
|
"dns": "kilo"
|
||||||
}`
|
}`
|
||||||
|
|
||||||
cfg := Config{
|
cfg := Config{
|
||||||
|
@ -126,6 +136,7 @@ func TestStore_Load(t *testing.T) {
|
||||||
ACLAgentRecoveryToken: "sierra",
|
ACLAgentRecoveryToken: "sierra",
|
||||||
ACLReplicationToken: "tango",
|
ACLReplicationToken: "tango",
|
||||||
ACLConfigFileRegistrationToken: "uniform",
|
ACLConfigFileRegistrationToken: "uniform",
|
||||||
|
ACLDNSToken: "victor",
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600))
|
require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600))
|
||||||
|
@ -136,43 +147,48 @@ func TestStore_Load(t *testing.T) {
|
||||||
require.Equal(t, "oscar", store.UserToken())
|
require.Equal(t, "oscar", store.UserToken())
|
||||||
require.Equal(t, "papa", store.ReplicationToken())
|
require.Equal(t, "papa", store.ReplicationToken())
|
||||||
require.Equal(t, "lima", store.ConfigFileRegistrationToken())
|
require.Equal(t, "lima", store.ConfigFileRegistrationToken())
|
||||||
|
require.Equal(t, "kilo", store.DNSToken())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("with some persisted tokens", func(t *testing.T) {
|
t.Run("with some persisted tokens", func(t *testing.T) {
|
||||||
tokens := `{
|
tokens := `{
|
||||||
"agent" : "uniform",
|
"agent" : "xray",
|
||||||
"agent_recovery" : "victor"
|
"agent_recovery" : "zulu"
|
||||||
}`
|
}`
|
||||||
|
|
||||||
cfg := Config{
|
cfg := Config{
|
||||||
EnablePersistence: true,
|
EnablePersistence: true,
|
||||||
DataDir: dataDir,
|
DataDir: dataDir,
|
||||||
ACLDefaultToken: "whiskey",
|
ACLDefaultToken: "alpha",
|
||||||
ACLAgentToken: "xray",
|
ACLAgentToken: "bravo",
|
||||||
ACLAgentRecoveryToken: "yankee",
|
ACLAgentRecoveryToken: "charlie",
|
||||||
ACLReplicationToken: "zulu",
|
ACLReplicationToken: "delta",
|
||||||
ACLConfigFileRegistrationToken: "victor",
|
ACLConfigFileRegistrationToken: "echo",
|
||||||
|
ACLDNSToken: "foxtrot",
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600))
|
require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600))
|
||||||
require.NoError(t, store.Load(cfg, logger))
|
require.NoError(t, store.Load(cfg, logger))
|
||||||
|
|
||||||
require.Equal(t, "uniform", store.AgentToken())
|
require.Equal(t, "xray", store.AgentToken())
|
||||||
require.Equal(t, "victor", store.AgentRecoveryToken())
|
require.Equal(t, "zulu", store.AgentRecoveryToken())
|
||||||
require.Equal(t, "whiskey", store.UserToken())
|
|
||||||
require.Equal(t, "zulu", store.ReplicationToken())
|
require.Equal(t, "alpha", store.UserToken())
|
||||||
require.Equal(t, "victor", store.ConfigFileRegistrationToken())
|
require.Equal(t, "delta", store.ReplicationToken())
|
||||||
|
require.Equal(t, "echo", store.ConfigFileRegistrationToken())
|
||||||
|
require.Equal(t, "foxtrot", store.DNSToken())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("persisted file contains invalid data", func(t *testing.T) {
|
t.Run("persisted file contains invalid data", func(t *testing.T) {
|
||||||
cfg := Config{
|
cfg := Config{
|
||||||
EnablePersistence: true,
|
EnablePersistence: true,
|
||||||
DataDir: dataDir,
|
DataDir: dataDir,
|
||||||
ACLDefaultToken: "one",
|
ACLDefaultToken: "alpha",
|
||||||
ACLAgentToken: "two",
|
ACLAgentToken: "bravo",
|
||||||
ACLAgentRecoveryToken: "three",
|
ACLAgentRecoveryToken: "charlie",
|
||||||
ACLReplicationToken: "four",
|
ACLReplicationToken: "delta",
|
||||||
ACLConfigFileRegistrationToken: "five",
|
ACLConfigFileRegistrationToken: "echo",
|
||||||
|
ACLDNSToken: "foxtrot",
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, os.WriteFile(tokenFile, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, 0600))
|
require.NoError(t, os.WriteFile(tokenFile, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, 0600))
|
||||||
|
@ -180,11 +196,12 @@ func TestStore_Load(t *testing.T) {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Contains(t, err.Error(), "failed to decode tokens file")
|
require.Contains(t, err.Error(), "failed to decode tokens file")
|
||||||
|
|
||||||
require.Equal(t, "one", store.UserToken())
|
require.Equal(t, "alpha", store.UserToken())
|
||||||
require.Equal(t, "two", store.AgentToken())
|
require.Equal(t, "bravo", store.AgentToken())
|
||||||
require.Equal(t, "three", store.AgentRecoveryToken())
|
require.Equal(t, "charlie", store.AgentRecoveryToken())
|
||||||
require.Equal(t, "four", store.ReplicationToken())
|
require.Equal(t, "delta", store.ReplicationToken())
|
||||||
require.Equal(t, "five", store.ConfigFileRegistrationToken())
|
require.Equal(t, "echo", store.ConfigFileRegistrationToken())
|
||||||
|
require.Equal(t, "foxtrot", store.DNSToken())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("persisted file contains invalid json", func(t *testing.T) {
|
t.Run("persisted file contains invalid json", func(t *testing.T) {
|
||||||
|
@ -194,8 +211,9 @@ func TestStore_Load(t *testing.T) {
|
||||||
ACLDefaultToken: "alfa",
|
ACLDefaultToken: "alfa",
|
||||||
ACLAgentToken: "bravo",
|
ACLAgentToken: "bravo",
|
||||||
ACLAgentRecoveryToken: "charlie",
|
ACLAgentRecoveryToken: "charlie",
|
||||||
ACLReplicationToken: "foxtrot",
|
ACLReplicationToken: "delta",
|
||||||
ACLConfigFileRegistrationToken: "golf",
|
ACLConfigFileRegistrationToken: "echo",
|
||||||
|
ACLDNSToken: "foxtrot",
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, os.WriteFile(tokenFile, []byte("[1,2,3]"), 0600))
|
require.NoError(t, os.WriteFile(tokenFile, []byte("[1,2,3]"), 0600))
|
||||||
|
@ -206,23 +224,31 @@ func TestStore_Load(t *testing.T) {
|
||||||
require.Equal(t, "alfa", store.UserToken())
|
require.Equal(t, "alfa", store.UserToken())
|
||||||
require.Equal(t, "bravo", store.AgentToken())
|
require.Equal(t, "bravo", store.AgentToken())
|
||||||
require.Equal(t, "charlie", store.AgentRecoveryToken())
|
require.Equal(t, "charlie", store.AgentRecoveryToken())
|
||||||
require.Equal(t, "foxtrot", store.ReplicationToken())
|
require.Equal(t, "delta", store.ReplicationToken())
|
||||||
require.Equal(t, "golf", store.ConfigFileRegistrationToken())
|
require.Equal(t, "echo", store.ConfigFileRegistrationToken())
|
||||||
|
require.Equal(t, "foxtrot", store.DNSToken())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStore_WithPersistenceLock(t *testing.T) {
|
func TestStore_WithPersistenceLock(t *testing.T) {
|
||||||
|
// ACLDefaultToken: alpha --> sierra
|
||||||
|
// ACLAgentToken: bravo --> tango
|
||||||
|
// ACLAgentRecoveryToken: charlie --> uniform
|
||||||
|
// ACLReplicationToken: delta --> victor
|
||||||
|
// ACLConfigFileRegistrationToken: echo --> xray
|
||||||
|
// ACLDNSToken: foxtrot --> zulu
|
||||||
setupStore := func() (string, *Store) {
|
setupStore := func() (string, *Store) {
|
||||||
dataDir := testutil.TempDir(t, "datadir")
|
dataDir := testutil.TempDir(t, "datadir")
|
||||||
store := new(Store)
|
store := new(Store)
|
||||||
cfg := Config{
|
cfg := Config{
|
||||||
EnablePersistence: true,
|
EnablePersistence: true,
|
||||||
DataDir: dataDir,
|
DataDir: dataDir,
|
||||||
ACLDefaultToken: "default-token",
|
ACLDefaultToken: "alpha",
|
||||||
ACLAgentToken: "agent-token",
|
ACLAgentToken: "bravo",
|
||||||
ACLAgentRecoveryToken: "recovery-token",
|
ACLAgentRecoveryToken: "charlie",
|
||||||
ACLReplicationToken: "replication-token",
|
ACLReplicationToken: "delta",
|
||||||
ACLConfigFileRegistrationToken: "registration-token",
|
ACLConfigFileRegistrationToken: "echo",
|
||||||
|
ACLDNSToken: "foxtrot",
|
||||||
}
|
}
|
||||||
err := store.Load(cfg, hclog.New(nil))
|
err := store.Load(cfg, hclog.New(nil))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -240,37 +266,39 @@ func TestStore_WithPersistenceLock(t *testing.T) {
|
||||||
t.Run("persist some tokens", func(t *testing.T) {
|
t.Run("persist some tokens", func(t *testing.T) {
|
||||||
dataDir, store := setupStore()
|
dataDir, store := setupStore()
|
||||||
err := store.WithPersistenceLock(func() error {
|
err := store.WithPersistenceLock(func() error {
|
||||||
require.True(t, store.UpdateUserToken("the-new-default-token", TokenSourceAPI))
|
require.True(t, store.UpdateUserToken("sierra", TokenSourceAPI))
|
||||||
require.True(t, store.UpdateAgentRecoveryToken("the-new-recovery-token", TokenSourceAPI))
|
require.True(t, store.UpdateAgentRecoveryToken("tango", TokenSourceAPI))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Only API-sourced tokens are persisted.
|
// Only API-sourced tokens are persisted.
|
||||||
requirePersistedTokens(t, dataDir, persistedTokens{
|
requirePersistedTokens(t, dataDir, persistedTokens{
|
||||||
Default: "the-new-default-token",
|
Default: "sierra",
|
||||||
AgentRecovery: "the-new-recovery-token",
|
AgentRecovery: "tango",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("persist all tokens", func(t *testing.T) {
|
t.Run("persist all tokens", func(t *testing.T) {
|
||||||
dataDir, store := setupStore()
|
dataDir, store := setupStore()
|
||||||
err := store.WithPersistenceLock(func() error {
|
err := store.WithPersistenceLock(func() error {
|
||||||
require.True(t, store.UpdateUserToken("the-new-default-token", TokenSourceAPI))
|
require.True(t, store.UpdateUserToken("sierra", TokenSourceAPI))
|
||||||
require.True(t, store.UpdateAgentToken("the-new-agent-token", TokenSourceAPI))
|
require.True(t, store.UpdateAgentToken("tango", TokenSourceAPI))
|
||||||
require.True(t, store.UpdateAgentRecoveryToken("the-new-recovery-token", TokenSourceAPI))
|
require.True(t, store.UpdateAgentRecoveryToken("uniform", TokenSourceAPI))
|
||||||
require.True(t, store.UpdateReplicationToken("the-new-replication-token", TokenSourceAPI))
|
require.True(t, store.UpdateReplicationToken("victor", TokenSourceAPI))
|
||||||
require.True(t, store.UpdateConfigFileRegistrationToken("the-new-registration-token", TokenSourceAPI))
|
require.True(t, store.UpdateConfigFileRegistrationToken("xray", TokenSourceAPI))
|
||||||
|
require.True(t, store.UpdateDNSToken("zulu", TokenSourceAPI))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
requirePersistedTokens(t, dataDir, persistedTokens{
|
requirePersistedTokens(t, dataDir, persistedTokens{
|
||||||
Default: "the-new-default-token",
|
Default: "sierra",
|
||||||
Agent: "the-new-agent-token",
|
Agent: "tango",
|
||||||
AgentRecovery: "the-new-recovery-token",
|
AgentRecovery: "uniform",
|
||||||
Replication: "the-new-replication-token",
|
Replication: "victor",
|
||||||
ConfigFileRegistration: "the-new-registration-token",
|
ConfigFileRegistration: "xray",
|
||||||
|
DNS: "zulu",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ const (
|
||||||
TokenKindUser
|
TokenKindUser
|
||||||
TokenKindReplication
|
TokenKindReplication
|
||||||
TokenKindConfigFileRegistration
|
TokenKindConfigFileRegistration
|
||||||
|
TokenKindDNS
|
||||||
)
|
)
|
||||||
|
|
||||||
type watcher struct {
|
type watcher struct {
|
||||||
|
@ -52,7 +53,7 @@ type Store struct {
|
||||||
// also be used for agent operations if the agent token isn't set.
|
// also be used for agent operations if the agent token isn't set.
|
||||||
userToken string
|
userToken string
|
||||||
|
|
||||||
// userTokenSource indicates where this token originated from
|
// userTokenSource indicates where this token originated from.
|
||||||
userTokenSource TokenSource
|
userTokenSource TokenSource
|
||||||
|
|
||||||
// agentToken is used for internal agent operations like self-registering
|
// agentToken is used for internal agent operations like self-registering
|
||||||
|
@ -60,7 +61,7 @@ type Store struct {
|
||||||
// user-initiated operations.
|
// user-initiated operations.
|
||||||
agentToken string
|
agentToken string
|
||||||
|
|
||||||
// agentTokenSource indicates where this token originated from
|
// agentTokenSource indicates where this token originated from.
|
||||||
agentTokenSource TokenSource
|
agentTokenSource TokenSource
|
||||||
|
|
||||||
// agentRecoveryToken is a special token that's only used locally for
|
// agentRecoveryToken is a special token that's only used locally for
|
||||||
|
@ -68,23 +69,30 @@ type Store struct {
|
||||||
// available.
|
// available.
|
||||||
agentRecoveryToken string
|
agentRecoveryToken string
|
||||||
|
|
||||||
// agentRecoveryTokenSource indicates where this token originated from
|
// agentRecoveryTokenSource indicates where this token originated from.
|
||||||
agentRecoveryTokenSource TokenSource
|
agentRecoveryTokenSource TokenSource
|
||||||
|
|
||||||
// replicationToken is a special token that's used by servers to
|
// replicationToken is a special token that's used by servers to
|
||||||
// replicate data from the primary datacenter.
|
// replicate data from the primary datacenter.
|
||||||
replicationToken string
|
replicationToken string
|
||||||
|
|
||||||
// replicationTokenSource indicates where this token originated from
|
// replicationTokenSource indicates where this token originated from.
|
||||||
replicationTokenSource TokenSource
|
replicationTokenSource TokenSource
|
||||||
|
|
||||||
// configFileRegistrationToken is used to register services and checks
|
// configFileRegistrationToken is used to register services and checks
|
||||||
// that are defined in configuration files.
|
// that are defined in configuration files.
|
||||||
configFileRegistrationToken string
|
configFileRegistrationToken string
|
||||||
|
|
||||||
// configFileRegistrationTokenSource indicates where this token originated from
|
// configFileRegistrationTokenSource indicates where this token originated from.
|
||||||
configFileRegistrationTokenSource TokenSource
|
configFileRegistrationTokenSource TokenSource
|
||||||
|
|
||||||
|
// dnsToken is a special token that is used as the implicit token for DNS requests
|
||||||
|
// as well as for DNS-specific RPC requests.
|
||||||
|
dnsToken string
|
||||||
|
|
||||||
|
// dnsTokenSource indicates where the dnsToken originated from.
|
||||||
|
dnsTokenSource TokenSource
|
||||||
|
|
||||||
watchers map[int]watcher
|
watchers map[int]watcher
|
||||||
watcherIndex int
|
watcherIndex int
|
||||||
|
|
||||||
|
@ -204,6 +212,12 @@ func (t *Store) UpdateConfigFileRegistrationToken(token string, source TokenSour
|
||||||
&t.configFileRegistrationTokenSource, TokenKindConfigFileRegistration)
|
&t.configFileRegistrationTokenSource, TokenKindConfigFileRegistration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateDNSToken replaces the current DNS token in the store.
|
||||||
|
// Returns true if it was changed.
|
||||||
|
func (t *Store) UpdateDNSToken(token string, source TokenSource) bool {
|
||||||
|
return t.updateToken(token, source, &t.dnsToken, &t.dnsTokenSource, TokenKindDNS)
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Store) updateToken(token string, source TokenSource, dstToken *string, dstSource *TokenSource, kind TokenKind) bool {
|
func (t *Store) updateToken(token string, source TokenSource, dstToken *string, dstSource *TokenSource, kind TokenKind) bool {
|
||||||
t.l.Lock()
|
t.l.Lock()
|
||||||
changed := *dstToken != token || *dstSource != source
|
changed := *dstToken != token || *dstSource != source
|
||||||
|
@ -261,6 +275,13 @@ func (t *Store) ConfigFileRegistrationToken() string {
|
||||||
return t.configFileRegistrationToken
|
return t.configFileRegistrationToken
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Store) DNSToken() string {
|
||||||
|
t.l.RLock()
|
||||||
|
defer t.l.RUnlock()
|
||||||
|
|
||||||
|
return t.dnsToken
|
||||||
|
}
|
||||||
|
|
||||||
// UserToken returns the best token to use for user operations.
|
// UserToken returns the best token to use for user operations.
|
||||||
func (t *Store) UserTokenAndSource() (string, TokenSource) {
|
func (t *Store) UserTokenAndSource() (string, TokenSource) {
|
||||||
t.l.RLock()
|
t.l.RLock()
|
||||||
|
@ -299,6 +320,14 @@ func (t *Store) ConfigFileRegistrationTokenAndSource() (string, TokenSource) {
|
||||||
return t.configFileRegistrationToken, t.configFileRegistrationTokenSource
|
return t.configFileRegistrationToken, t.configFileRegistrationTokenSource
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DNSTokenAndSource returns the best token to use for DNS-specific RPC requests and DNS requests
|
||||||
|
func (t *Store) DNSTokenAndSource() (string, TokenSource) {
|
||||||
|
t.l.RLock()
|
||||||
|
defer t.l.RUnlock()
|
||||||
|
|
||||||
|
return t.dnsToken, t.dnsTokenSource
|
||||||
|
}
|
||||||
|
|
||||||
// IsAgentRecoveryToken checks to see if a given token is the agent recovery token.
|
// IsAgentRecoveryToken checks to see if a given token is the agent recovery token.
|
||||||
// This will never match an empty token for safety.
|
// This will never match an empty token for safety.
|
||||||
func (t *Store) IsAgentRecoveryToken(token string) bool {
|
func (t *Store) IsAgentRecoveryToken(token string) bool {
|
||||||
|
|
|
@ -21,6 +21,8 @@ func TestStore_RegularTokens(t *testing.T) {
|
||||||
replSource TokenSource
|
replSource TokenSource
|
||||||
registration string
|
registration string
|
||||||
registrationSource TokenSource
|
registrationSource TokenSource
|
||||||
|
dns string
|
||||||
|
dnsSource TokenSource
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -95,11 +97,23 @@ func TestStore_RegularTokens(t *testing.T) {
|
||||||
raw: tokens{registration: "G", registrationSource: TokenSourceAPI},
|
raw: tokens{registration: "G", registrationSource: TokenSourceAPI},
|
||||||
effective: tokens{registration: "G"},
|
effective: tokens{registration: "G"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "set dns - config",
|
||||||
|
set: tokens{dns: "D", dnsSource: TokenSourceConfig},
|
||||||
|
raw: tokens{dns: "D", dnsSource: TokenSourceConfig},
|
||||||
|
effective: tokens{dns: "D"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "set dns - api",
|
||||||
|
set: tokens{dns: "D", dnsSource: TokenSourceAPI},
|
||||||
|
raw: tokens{dns: "D", dnsSource: TokenSourceAPI},
|
||||||
|
effective: tokens{dns: "D"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "set all",
|
name: "set all",
|
||||||
set: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G"},
|
set: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G", dns: "D"},
|
||||||
raw: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G"},
|
raw: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G", dns: "D"},
|
||||||
effective: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G"},
|
effective: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G", dns: "D"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
@ -125,18 +139,24 @@ func TestStore_RegularTokens(t *testing.T) {
|
||||||
require.True(t, s.UpdateConfigFileRegistrationToken(tt.set.registration, tt.set.registrationSource))
|
require.True(t, s.UpdateConfigFileRegistrationToken(tt.set.registration, tt.set.registrationSource))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tt.set.dns != "" {
|
||||||
|
require.True(t, s.UpdateDNSToken(tt.set.dns, tt.set.dnsSource))
|
||||||
|
}
|
||||||
|
|
||||||
// If they don't change then they return false.
|
// If they don't change then they return false.
|
||||||
require.False(t, s.UpdateUserToken(tt.set.user, tt.set.userSource))
|
require.False(t, s.UpdateUserToken(tt.set.user, tt.set.userSource))
|
||||||
require.False(t, s.UpdateAgentToken(tt.set.agent, tt.set.agentSource))
|
require.False(t, s.UpdateAgentToken(tt.set.agent, tt.set.agentSource))
|
||||||
require.False(t, s.UpdateReplicationToken(tt.set.repl, tt.set.replSource))
|
require.False(t, s.UpdateReplicationToken(tt.set.repl, tt.set.replSource))
|
||||||
require.False(t, s.UpdateAgentRecoveryToken(tt.set.recovery, tt.set.recoverySource))
|
require.False(t, s.UpdateAgentRecoveryToken(tt.set.recovery, tt.set.recoverySource))
|
||||||
require.False(t, s.UpdateConfigFileRegistrationToken(tt.set.registration, tt.set.registrationSource))
|
require.False(t, s.UpdateConfigFileRegistrationToken(tt.set.registration, tt.set.registrationSource))
|
||||||
|
require.False(t, s.UpdateDNSToken(tt.set.dns, tt.set.dnsSource))
|
||||||
|
|
||||||
require.Equal(t, tt.effective.user, s.UserToken())
|
require.Equal(t, tt.effective.user, s.UserToken())
|
||||||
require.Equal(t, tt.effective.agent, s.AgentToken())
|
require.Equal(t, tt.effective.agent, s.AgentToken())
|
||||||
require.Equal(t, tt.effective.recovery, s.AgentRecoveryToken())
|
require.Equal(t, tt.effective.recovery, s.AgentRecoveryToken())
|
||||||
require.Equal(t, tt.effective.repl, s.ReplicationToken())
|
require.Equal(t, tt.effective.repl, s.ReplicationToken())
|
||||||
require.Equal(t, tt.effective.registration, s.ConfigFileRegistrationToken())
|
require.Equal(t, tt.effective.registration, s.ConfigFileRegistrationToken())
|
||||||
|
require.Equal(t, tt.effective.dns, s.DNSToken())
|
||||||
|
|
||||||
tok, src := s.UserTokenAndSource()
|
tok, src := s.UserTokenAndSource()
|
||||||
require.Equal(t, tt.raw.user, tok)
|
require.Equal(t, tt.raw.user, tok)
|
||||||
|
@ -157,6 +177,10 @@ func TestStore_RegularTokens(t *testing.T) {
|
||||||
tok, src = s.ConfigFileRegistrationTokenAndSource()
|
tok, src = s.ConfigFileRegistrationTokenAndSource()
|
||||||
require.Equal(t, tt.raw.registration, tok)
|
require.Equal(t, tt.raw.registration, tok)
|
||||||
require.Equal(t, tt.raw.registrationSource, src)
|
require.Equal(t, tt.raw.registrationSource, src)
|
||||||
|
|
||||||
|
tok, src = s.DNSTokenAndSource()
|
||||||
|
require.Equal(t, tt.raw.dns, tok)
|
||||||
|
require.Equal(t, tt.raw.dnsSource, src)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,6 +235,7 @@ func TestStore_Notify(t *testing.T) {
|
||||||
replicationNotifier := newNotification(t, s, TokenKindReplication)
|
replicationNotifier := newNotification(t, s, TokenKindReplication)
|
||||||
replicationNotifier2 := newNotification(t, s, TokenKindReplication)
|
replicationNotifier2 := newNotification(t, s, TokenKindReplication)
|
||||||
registrationNotifier := newNotification(t, s, TokenKindConfigFileRegistration)
|
registrationNotifier := newNotification(t, s, TokenKindConfigFileRegistration)
|
||||||
|
dnsNotifier := newNotification(t, s, TokenKindDNS)
|
||||||
|
|
||||||
// perform an update of the user token
|
// perform an update of the user token
|
||||||
require.True(t, s.UpdateUserToken("edcae2a2-3b51-4864-b412-c7a568f49cb1", TokenSourceConfig))
|
require.True(t, s.UpdateUserToken("edcae2a2-3b51-4864-b412-c7a568f49cb1", TokenSourceConfig))
|
||||||
|
@ -224,6 +249,7 @@ func TestStore_Notify(t *testing.T) {
|
||||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||||
requireNotNotified(t, replicationNotifier2.Ch)
|
requireNotNotified(t, replicationNotifier2.Ch)
|
||||||
requireNotNotified(t, registrationNotifier.Ch)
|
requireNotNotified(t, registrationNotifier.Ch)
|
||||||
|
requireNotNotified(t, dnsNotifier.Ch)
|
||||||
|
|
||||||
// update the agent token which should send a notification to the agent notifier.
|
// update the agent token which should send a notification to the agent notifier.
|
||||||
require.True(t, s.UpdateAgentToken("5d748ec2-d536-461f-8e2a-1f7eae98d559", TokenSourceAPI))
|
require.True(t, s.UpdateAgentToken("5d748ec2-d536-461f-8e2a-1f7eae98d559", TokenSourceAPI))
|
||||||
|
@ -234,6 +260,7 @@ func TestStore_Notify(t *testing.T) {
|
||||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||||
requireNotNotified(t, replicationNotifier2.Ch)
|
requireNotNotified(t, replicationNotifier2.Ch)
|
||||||
requireNotNotified(t, registrationNotifier.Ch)
|
requireNotNotified(t, registrationNotifier.Ch)
|
||||||
|
requireNotNotified(t, dnsNotifier.Ch)
|
||||||
|
|
||||||
// update the agent recovery token which should send a notification to the agent recovery notifier.
|
// update the agent recovery token which should send a notification to the agent recovery notifier.
|
||||||
require.True(t, s.UpdateAgentRecoveryToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
require.True(t, s.UpdateAgentRecoveryToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
||||||
|
@ -244,6 +271,7 @@ func TestStore_Notify(t *testing.T) {
|
||||||
requireNotifiedOnce(t, agentRecoveryNotifier.Ch)
|
requireNotifiedOnce(t, agentRecoveryNotifier.Ch)
|
||||||
requireNotNotified(t, replicationNotifier2.Ch)
|
requireNotNotified(t, replicationNotifier2.Ch)
|
||||||
requireNotNotified(t, registrationNotifier.Ch)
|
requireNotNotified(t, registrationNotifier.Ch)
|
||||||
|
requireNotNotified(t, dnsNotifier.Ch)
|
||||||
|
|
||||||
// update the replication token which should send a notification to the replication notifier.
|
// update the replication token which should send a notification to the replication notifier.
|
||||||
require.True(t, s.UpdateReplicationToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
require.True(t, s.UpdateReplicationToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
||||||
|
@ -254,6 +282,7 @@ func TestStore_Notify(t *testing.T) {
|
||||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||||
requireNotifiedOnce(t, replicationNotifier2.Ch)
|
requireNotifiedOnce(t, replicationNotifier2.Ch)
|
||||||
requireNotNotified(t, registrationNotifier.Ch)
|
requireNotNotified(t, registrationNotifier.Ch)
|
||||||
|
requireNotNotified(t, dnsNotifier.Ch)
|
||||||
|
|
||||||
s.StopNotify(replicationNotifier2)
|
s.StopNotify(replicationNotifier2)
|
||||||
|
|
||||||
|
@ -266,6 +295,7 @@ func TestStore_Notify(t *testing.T) {
|
||||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||||
requireNotNotified(t, replicationNotifier2.Ch)
|
requireNotNotified(t, replicationNotifier2.Ch)
|
||||||
requireNotNotified(t, registrationNotifier.Ch)
|
requireNotNotified(t, registrationNotifier.Ch)
|
||||||
|
requireNotNotified(t, dnsNotifier.Ch)
|
||||||
|
|
||||||
// update the config file registration token which should send a notification to the replication notifier.
|
// update the config file registration token which should send a notification to the replication notifier.
|
||||||
require.True(t, s.UpdateConfigFileRegistrationToken("82fe7362-7d83-4f43-bb27-c35f1f15083c", TokenSourceAPI))
|
require.True(t, s.UpdateConfigFileRegistrationToken("82fe7362-7d83-4f43-bb27-c35f1f15083c", TokenSourceAPI))
|
||||||
|
@ -276,6 +306,18 @@ func TestStore_Notify(t *testing.T) {
|
||||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||||
requireNotNotified(t, replicationNotifier2.Ch)
|
requireNotNotified(t, replicationNotifier2.Ch)
|
||||||
requireNotifiedOnce(t, registrationNotifier.Ch)
|
requireNotifiedOnce(t, registrationNotifier.Ch)
|
||||||
|
requireNotNotified(t, dnsNotifier.Ch)
|
||||||
|
|
||||||
|
// update the dns token which should send a notification to the replication notifier.
|
||||||
|
require.True(t, s.UpdateDNSToken("ce8e829f-dc45-4ba7-9dd3-1dbbe070f573", TokenSourceAPI))
|
||||||
|
|
||||||
|
requireNotNotified(t, agentNotifier.Ch)
|
||||||
|
requireNotNotified(t, userNotifier.Ch)
|
||||||
|
requireNotNotified(t, replicationNotifier.Ch)
|
||||||
|
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||||
|
requireNotNotified(t, replicationNotifier2.Ch)
|
||||||
|
requireNotNotified(t, registrationNotifier.Ch)
|
||||||
|
requireNotifiedOnce(t, dnsNotifier.Ch)
|
||||||
|
|
||||||
// request updates that are not changes
|
// request updates that are not changes
|
||||||
require.False(t, s.UpdateAgentToken("5d748ec2-d536-461f-8e2a-1f7eae98d559", TokenSourceAPI))
|
require.False(t, s.UpdateAgentToken("5d748ec2-d536-461f-8e2a-1f7eae98d559", TokenSourceAPI))
|
||||||
|
@ -283,6 +325,7 @@ func TestStore_Notify(t *testing.T) {
|
||||||
require.False(t, s.UpdateUserToken("47788919-f944-476a-bda5-446d64be1df8", TokenSourceAPI))
|
require.False(t, s.UpdateUserToken("47788919-f944-476a-bda5-446d64be1df8", TokenSourceAPI))
|
||||||
require.False(t, s.UpdateReplicationToken("eb0b56b9-fa65-4ae1-902a-c64457c62ac6", TokenSourceAPI))
|
require.False(t, s.UpdateReplicationToken("eb0b56b9-fa65-4ae1-902a-c64457c62ac6", TokenSourceAPI))
|
||||||
require.False(t, s.UpdateConfigFileRegistrationToken("82fe7362-7d83-4f43-bb27-c35f1f15083c", TokenSourceAPI))
|
require.False(t, s.UpdateConfigFileRegistrationToken("82fe7362-7d83-4f43-bb27-c35f1f15083c", TokenSourceAPI))
|
||||||
|
require.False(t, s.UpdateDNSToken("ce8e829f-dc45-4ba7-9dd3-1dbbe070f573", TokenSourceAPI))
|
||||||
|
|
||||||
// ensure that notifications were not sent
|
// ensure that notifications were not sent
|
||||||
requireNotNotified(t, agentNotifier.Ch)
|
requireNotNotified(t, agentNotifier.Ch)
|
||||||
|
@ -290,4 +333,5 @@ func TestStore_Notify(t *testing.T) {
|
||||||
requireNotNotified(t, replicationNotifier.Ch)
|
requireNotNotified(t, replicationNotifier.Ch)
|
||||||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||||
requireNotNotified(t, registrationNotifier.Ch)
|
requireNotNotified(t, registrationNotifier.Ch)
|
||||||
|
requireNotNotified(t, dnsNotifier.Ch)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1379,6 +1379,10 @@ func (a *Agent) UpdateConfigFileRegistrationToken(token string, q *WriteOptions)
|
||||||
return a.updateToken("config_file_service_registration", token, q)
|
return a.updateToken("config_file_service_registration", token, q)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Agent) UpdateDNSToken(token string, q *WriteOptions) (*WriteMeta, error) {
|
||||||
|
return a.updateToken("dns", token, q)
|
||||||
|
}
|
||||||
|
|
||||||
// updateToken can be used to update one of an agent's ACL tokens after the agent has
|
// updateToken can be used to update one of an agent's ACL tokens after the agent has
|
||||||
// started. The tokens are may not be persisted, so will need to be updated again if
|
// started. The tokens are may not be persisted, so will need to be updated again if
|
||||||
// the agent is restarted unless the agent is configured to persist them.
|
// the agent is restarted unless the agent is configured to persist them.
|
||||||
|
|
|
@ -1635,6 +1635,10 @@ func TestAPI_AgentUpdateToken(t *testing.T) {
|
||||||
t.Fatalf("err: %v", err)
|
t.Fatalf("err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err := agent.UpdateDNSToken("root", nil); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("new with fallback", func(t *testing.T) {
|
t.Run("new with fallback", func(t *testing.T) {
|
||||||
|
@ -1723,6 +1727,9 @@ func TestAPI_AgentUpdateToken(t *testing.T) {
|
||||||
|
|
||||||
_, err = agent.UpdateConfigFileRegistrationToken("root", nil)
|
_, err = agent.UpdateConfigFileRegistrationToken("root", nil)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = agent.UpdateDNSToken("root", nil)
|
||||||
|
require.Error(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/mitchellh/cli"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/command/flags"
|
"github.com/hashicorp/consul/command/flags"
|
||||||
"github.com/hashicorp/consul/command/helpers"
|
"github.com/hashicorp/consul/command/helpers"
|
||||||
"github.com/mitchellh/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(ui cli.Ui) *cmd {
|
func New(ui cli.Ui) *cmd {
|
||||||
|
@ -63,6 +64,8 @@ func (c *cmd) Run(args []string) int {
|
||||||
_, err = client.Agent().UpdateReplicationACLToken(token, nil)
|
_, err = client.Agent().UpdateReplicationACLToken(token, nil)
|
||||||
case "config_file_service_registration":
|
case "config_file_service_registration":
|
||||||
_, err = client.Agent().UpdateConfigFileRegistrationToken(token, nil)
|
_, err = client.Agent().UpdateConfigFileRegistrationToken(token, nil)
|
||||||
|
case "dns":
|
||||||
|
_, err = client.Agent().UpdateDNSToken(token, nil)
|
||||||
default:
|
default:
|
||||||
c.UI.Error(fmt.Sprintf("Unknown token type"))
|
c.UI.Error(fmt.Sprintf("Unknown token type"))
|
||||||
return 1
|
return 1
|
||||||
|
@ -140,6 +143,11 @@ Usage: consul acl set-agent-token [options] TYPE TOKEN
|
||||||
If a service or check definition contains a 'token'
|
If a service or check definition contains a 'token'
|
||||||
field, then that token is used instead.
|
field, then that token is used instead.
|
||||||
|
|
||||||
|
dns This is the token that the will be used in place of the default
|
||||||
|
token when specified for DNS requests and for DNS-specific RPCs.
|
||||||
|
If not provided the agent will attempt to use the default token
|
||||||
|
if one is present, then fallback to the anonymous token.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ consul acl set-agent-token default c4d0f8df-3aba-4ab6-a7a0-35b760dc29a1
|
$ consul acl set-agent-token default c4d0f8df-3aba-4ab6-a7a0-35b760dc29a1
|
||||||
|
|
|
@ -6,7 +6,7 @@ require (
|
||||||
github.com/hashicorp/consul/api v1.24.0
|
github.com/hashicorp/consul/api v1.24.0
|
||||||
github.com/hashicorp/consul/sdk v0.14.1
|
github.com/hashicorp/consul/sdk v0.14.1
|
||||||
github.com/hashicorp/consul/test/integration/consul-container v0.0.0-20230628201853-bdf4fad7c5a5
|
github.com/hashicorp/consul/test/integration/consul-container v0.0.0-20230628201853-bdf4fad7c5a5
|
||||||
github.com/hashicorp/consul/testing/deployer v0.0.0-00010101000000-000000000000
|
github.com/hashicorp/consul/testing/deployer v0.0.0-20230811171106-4a0afb5d1373
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2
|
github.com/hashicorp/go-cleanhttp v0.5.2
|
||||||
github.com/itchyny/gojq v0.12.13
|
github.com/itchyny/gojq v0.12.13
|
||||||
github.com/mitchellh/copystructure v1.2.0
|
github.com/mitchellh/copystructure v1.2.0
|
||||||
|
|
|
@ -14,7 +14,7 @@ require (
|
||||||
github.com/hashicorp/consul/envoyextensions v0.4.1
|
github.com/hashicorp/consul/envoyextensions v0.4.1
|
||||||
github.com/hashicorp/consul/proto-public v0.4.1
|
github.com/hashicorp/consul/proto-public v0.4.1
|
||||||
github.com/hashicorp/consul/sdk v0.14.1
|
github.com/hashicorp/consul/sdk v0.14.1
|
||||||
github.com/hashicorp/consul/testing/deployer v0.0.0-00010101000000-000000000000
|
github.com/hashicorp/consul/testing/deployer v0.0.0-20230811171106-4a0afb5d1373
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2
|
github.com/hashicorp/go-cleanhttp v0.5.2
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
github.com/hashicorp/go-uuid v1.0.3
|
github.com/hashicorp/go-uuid v1.0.3
|
||||||
|
|
|
@ -114,7 +114,7 @@ func AssertUpstreamEndpointStatusWithClient(
|
||||||
| length`,
|
| length`,
|
||||||
clusterName, healthStatus)
|
clusterName, healthStatus)
|
||||||
results, err := utils.JQFilter(clusters, filter)
|
results, err := utils.JQFilter(clusters, filter)
|
||||||
require.NoErrorf(r, err, "could not found cluster name %q: %v \n%s", clusterName, err, clusters)
|
require.NoErrorf(r, err, "could not find cluster name %q: %v \n%s", clusterName, err, clusters)
|
||||||
require.Len(r, results, 1) // the final part of the pipeline is "length" which only ever returns 1 result
|
require.Len(r, results, 1) // the final part of the pipeline is "length" which only ever returns 1 result
|
||||||
|
|
||||||
result, err := strconv.Atoi(results[0])
|
result, err := strconv.Atoi(results[0])
|
||||||
|
|
|
@ -614,6 +614,7 @@ func newContainerRequest(config Config, opts containerOpts, ports ...int) (podRe
|
||||||
"8500/tcp", // Consul HTTP API
|
"8500/tcp", // Consul HTTP API
|
||||||
"8501/tcp", // Consul HTTPs API
|
"8501/tcp", // Consul HTTPs API
|
||||||
"8502/tcp", // Consul gRPC API
|
"8502/tcp", // Consul gRPC API
|
||||||
|
"8600/udp", // Consul DNS API
|
||||||
|
|
||||||
"8443/tcp", // Envoy Gateway Listener
|
"8443/tcp", // Envoy Gateway Listener
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ type PeeringClusterSize struct {
|
||||||
//
|
//
|
||||||
// - an accepting cluster with 3 servers and 1 client agent. The client should be used to
|
// - an accepting cluster with 3 servers and 1 client agent. The client should be used to
|
||||||
// host a service for export: staticServerSvc.
|
// host a service for export: staticServerSvc.
|
||||||
// - an dialing cluster with 1 server and 1 client. The client should be used to host a
|
// - a dialing cluster with 1 server and 1 client. The client should be used to host a
|
||||||
// service connecting to staticServerSvc.
|
// service connecting to staticServerSvc.
|
||||||
// - Create the peering, export the service from accepting cluster, and verify service
|
// - Create the peering, export the service from accepting cluster, and verify service
|
||||||
// connectivity.
|
// connectivity.
|
||||||
|
@ -120,7 +120,7 @@ func BasicPeeringTwoClustersSetup(
|
||||||
libassert.PeeringStatus(t, acceptingClient, AcceptingPeerName, api.PeeringStateActive)
|
libassert.PeeringStatus(t, acceptingClient, AcceptingPeerName, api.PeeringStateActive)
|
||||||
// libassert.PeeringExports(t, acceptingClient, acceptingPeerName, 1)
|
// libassert.PeeringExports(t, acceptingClient, acceptingPeerName, 1)
|
||||||
|
|
||||||
// Register an static-server service in acceptingCluster and export to dialing cluster
|
// Register a static-server service in acceptingCluster and export to dialing cluster
|
||||||
var serverService, serverSidecarService libservice.Service
|
var serverService, serverSidecarService libservice.Service
|
||||||
{
|
{
|
||||||
clientNode := acceptingCluster.Clients()[0]
|
clientNode := acceptingCluster.Clients()[0]
|
||||||
|
@ -144,7 +144,7 @@ func BasicPeeringTwoClustersSetup(
|
||||||
require.NoError(t, serverService.Export("default", AcceptingPeerName, acceptingClient))
|
require.NoError(t, serverService.Export("default", AcceptingPeerName, acceptingClient))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register an static-client service in dialing cluster and set upstream to static-server service
|
// Register a static-client service in dialing cluster and set upstream to static-server service
|
||||||
var clientSidecarService *libservice.ConnectContainer
|
var clientSidecarService *libservice.ConnectContainer
|
||||||
{
|
{
|
||||||
clientNode := dialingCluster.Clients()[0]
|
clientNode := dialingCluster.Clients()[0]
|
||||||
|
@ -268,11 +268,11 @@ func NewClusterWithConfig(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add numClients static clients to register the service
|
// Add numClients static clients to register the service
|
||||||
configbuiilder := libcluster.NewConfigBuilder(ctx).
|
configBuilder := libcluster.NewConfigBuilder(ctx).
|
||||||
Client().
|
Client().
|
||||||
Peering(true).
|
Peering(true).
|
||||||
RetryJoin(retryJoin...)
|
RetryJoin(retryJoin...)
|
||||||
clientConf := configbuiilder.ToAgentConfig(t)
|
clientConf := configBuilder.ToAgentConfig(t)
|
||||||
t.Logf("%s client config: \n%s", opts.Datacenter, clientConf.JSON)
|
t.Logf("%s client config: \n%s", opts.Datacenter, clientConf.JSON)
|
||||||
if clientHclConfig != "" {
|
if clientHclConfig != "" {
|
||||||
clientConf.MutatebyAgentConfig(clientHclConfig)
|
clientConf.MutatebyAgentConfig(clientHclConfig)
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
|
|
||||||
package topology
|
package topology
|
||||||
|
|
||||||
const DefaultDataplaneImage = "hashicorp/consul-dataplane:1.1.0"
|
const DefaultDataplaneImage = "hashicorp/consul-dataplane:1.2.1"
|
||||||
|
|
Loading…
Reference in New Issue