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":
|
||||
s.agent.tokens.UpdateConfigFileRegistrationToken(args.Token, token_store.TokenSourceAPI)
|
||||
|
||||
case "dns_token", "dns":
|
||||
s.agent.tokens.UpdateDNSToken(args.Token, token_store.TokenSourceAPI)
|
||||
|
||||
default:
|
||||
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),
|
||||
ACLReplicationToken: stringVal(c.ACL.Tokens.Replication),
|
||||
ACLConfigFileRegistrationToken: stringVal(c.ACL.Tokens.ConfigFileRegistration),
|
||||
ACLDNSToken: stringVal(c.ACL.Tokens.DNS),
|
||||
},
|
||||
|
||||
// Autopilot
|
||||
|
|
|
@ -778,6 +778,7 @@ type Tokens struct {
|
|||
Default *string `mapstructure:"default"`
|
||||
Agent *string `mapstructure:"agent"`
|
||||
ConfigFileRegistration *string `mapstructure:"config_file_service_registration"`
|
||||
DNS *string `mapstructure:"dns"`
|
||||
|
||||
// Enterprise Only
|
||||
ManagedServiceProvider []ServiceProviderToken `mapstructure:"managed_service_provider"`
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
"ACLAgentRecoveryToken": "hidden",
|
||||
"ACLAgentToken": "hidden",
|
||||
"ACLConfigFileRegistrationToken": "hidden",
|
||||
"ACLDNSToken": "hidden",
|
||||
"ACLDefaultToken": "hidden",
|
||||
"ACLReplicationToken": "hidden",
|
||||
"DataDir": "",
|
||||
|
|
20
agent/dns.go
20
agent/dns.go
|
@ -416,7 +416,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) {
|
|||
args := structs.DCSpecificRequest{
|
||||
Datacenter: datacenter,
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Token: d.agent.tokens.UserToken(),
|
||||
Token: d.coalesceDNSToken(),
|
||||
AllowStale: cfg.AllowStale,
|
||||
},
|
||||
}
|
||||
|
@ -452,7 +452,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) {
|
|||
sargs := structs.ServiceSpecificRequest{
|
||||
Datacenter: datacenter,
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Token: d.agent.tokens.UserToken(),
|
||||
Token: d.coalesceDNSToken(),
|
||||
AllowStale: cfg.AllowStale,
|
||||
},
|
||||
ServiceAddress: serviceAddress,
|
||||
|
@ -875,7 +875,7 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi
|
|||
ServiceName: queryParts[len(queryParts)-1],
|
||||
EnterpriseMeta: locality.EnterpriseMeta,
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Token: d.agent.tokens.UserToken(),
|
||||
Token: d.coalesceDNSToken(),
|
||||
},
|
||||
}
|
||||
if args.PeerName == "" {
|
||||
|
@ -1093,7 +1093,7 @@ func (d *DNSServer) nodeLookup(cfg *dnsConfig, lookup nodeLookup, req, resp *dns
|
|||
PeerName: lookup.PeerName,
|
||||
Node: lookup.Node,
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Token: d.agent.tokens.UserToken(),
|
||||
Token: d.coalesceDNSToken(),
|
||||
AllowStale: cfg.AllowStale,
|
||||
},
|
||||
EnterpriseMeta: lookup.EnterpriseMeta,
|
||||
|
@ -1425,7 +1425,7 @@ func (d *DNSServer) lookupServiceNodes(cfg *dnsConfig, lookup serviceLookup) (st
|
|||
ServiceTags: serviceTags,
|
||||
TagFilter: lookup.Tag != "",
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Token: d.agent.tokens.UserToken(),
|
||||
Token: d.coalesceDNSToken(),
|
||||
AllowStale: cfg.AllowStale,
|
||||
MaxAge: cfg.CacheMaxAge,
|
||||
UseCache: cfg.UseCache,
|
||||
|
@ -1503,7 +1503,7 @@ func (d *DNSServer) preparedQueryLookup(cfg *dnsConfig, datacenter, query string
|
|||
Datacenter: datacenter,
|
||||
QueryIDOrName: query,
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Token: d.agent.tokens.UserToken(),
|
||||
Token: d.coalesceDNSToken(),
|
||||
AllowStale: cfg.AllowStale,
|
||||
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)
|
||||
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"
|
||||
"testing"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/acl"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/testrpc"
|
||||
"github.com/miekg/dns"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
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) {
|
||||
if testing.Short() {
|
||||
t.Skip("too slow for testing.Short")
|
||||
|
@ -6322,10 +6338,11 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
|
|||
}{
|
||||
{"root", 1},
|
||||
{"anonymous", 0},
|
||||
{"dns", 1},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run("ACLToken == "+tt.token, func(t *testing.T) {
|
||||
a := NewTestAgent(t, `
|
||||
hcl := `
|
||||
primary_datacenter = "dc1"
|
||||
|
||||
acl {
|
||||
|
@ -6335,13 +6352,34 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
|
|||
|
||||
tokens {
|
||||
initial_management = "root"
|
||||
`
|
||||
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()
|
||||
testrpc.WaitForLeader(t, a.RPC, "dc1")
|
||||
|
||||
if tt.token == "dns" {
|
||||
initDNSToken(t, a)
|
||||
}
|
||||
|
||||
// Register a service
|
||||
args := &structs.RegisterRequest{
|
||||
Datacenter: "dc1",
|
||||
|
@ -6373,6 +6411,7 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDNS_ServiceLookup_MetaTXT(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("too slow for testing.Short")
|
||||
|
|
|
@ -529,6 +529,7 @@ type TestACLConfigParams struct {
|
|||
DefaultToken string
|
||||
AgentRecoveryToken string
|
||||
ReplicationToken string
|
||||
DNSToken string
|
||||
EnableTokenReplication bool
|
||||
}
|
||||
|
||||
|
@ -547,7 +548,8 @@ func (p *TestACLConfigParams) HasConfiguredTokens() bool {
|
|||
p.AgentToken != "" ||
|
||||
p.DefaultToken != "" ||
|
||||
p.AgentRecoveryToken != "" ||
|
||||
p.ReplicationToken != ""
|
||||
p.ReplicationToken != "" ||
|
||||
p.DNSToken != ""
|
||||
}
|
||||
|
||||
func TestACLConfigNew() string {
|
||||
|
@ -557,6 +559,7 @@ func TestACLConfigNew() string {
|
|||
InitialManagementToken: "root",
|
||||
AgentToken: "root",
|
||||
AgentRecoveryToken: "towel",
|
||||
DNSToken: "dns",
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ type Config struct {
|
|||
ACLAgentRecoveryToken string
|
||||
ACLReplicationToken string
|
||||
ACLConfigFileRegistrationToken string
|
||||
ACLDNSToken string
|
||||
|
||||
EnterpriseConfig
|
||||
}
|
||||
|
@ -77,6 +78,7 @@ type persistedTokens struct {
|
|||
Default string `json:"default,omitempty"`
|
||||
Agent string `json:"agent,omitempty"`
|
||||
ConfigFileRegistration string `json:"config_file_service_registration,omitempty"`
|
||||
DNS string `json:"dns,omitempty"`
|
||||
}
|
||||
|
||||
type fileStore struct {
|
||||
|
@ -144,6 +146,16 @@ func loadTokens(s *Store, cfg Config, tokens persistedTokens, logger Logger) {
|
|||
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)
|
||||
}
|
||||
|
||||
|
@ -206,6 +218,10 @@ func (p *fileStore) saveToFile(s *Store) error {
|
|||
tokens.ConfigFileRegistration = tok
|
||||
}
|
||||
|
||||
if tok, source := s.DNSTokenAndSource(); tok != "" && source == TokenSourceAPI {
|
||||
tokens.DNS = tok
|
||||
}
|
||||
|
||||
data, err := json.Marshal(tokens)
|
||||
if err != nil {
|
||||
p.logger.Warn("failed to persist tokens", "error", err)
|
||||
|
|
|
@ -8,9 +8,10 @@ import (
|
|||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/sdk/testutil"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/sdk/testutil"
|
||||
)
|
||||
|
||||
func TestStore_Load(t *testing.T) {
|
||||
|
@ -27,6 +28,7 @@ func TestStore_Load(t *testing.T) {
|
|||
ACLDefaultToken: "charlie",
|
||||
ACLReplicationToken: "delta",
|
||||
ACLConfigFileRegistrationToken: "echo",
|
||||
ACLDNSToken: "foxtrot",
|
||||
}
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
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, "delta", store.ReplicationToken())
|
||||
require.Equal(t, "echo", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "foxtrot", store.DNSToken())
|
||||
})
|
||||
|
||||
t.Run("updated from Config", func(t *testing.T) {
|
||||
cfg := Config{
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "echo",
|
||||
ACLAgentToken: "foxtrot",
|
||||
ACLAgentRecoveryToken: "golf",
|
||||
ACLReplicationToken: "hotel",
|
||||
ACLConfigFileRegistrationToken: "india",
|
||||
ACLDefaultToken: "sierra",
|
||||
ACLAgentToken: "tango",
|
||||
ACLAgentRecoveryToken: "uniform",
|
||||
ACLReplicationToken: "victor",
|
||||
ACLConfigFileRegistrationToken: "xray",
|
||||
ACLDNSToken: "zulu",
|
||||
}
|
||||
// ensures no error for missing persisted tokens file
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
require.Equal(t, "echo", store.UserToken())
|
||||
require.Equal(t, "foxtrot", store.AgentToken())
|
||||
require.Equal(t, "golf", store.AgentRecoveryToken())
|
||||
require.Equal(t, "hotel", store.ReplicationToken())
|
||||
require.Equal(t, "india", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "sierra", store.UserToken())
|
||||
require.Equal(t, "tango", store.AgentToken())
|
||||
require.Equal(t, "uniform", store.AgentRecoveryToken())
|
||||
require.Equal(t, "victor", store.ReplicationToken())
|
||||
require.Equal(t, "xray", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "zulu", store.DNSToken())
|
||||
})
|
||||
|
||||
t.Run("with persisted tokens", func(t *testing.T) {
|
||||
cfg := Config{
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "echo",
|
||||
ACLAgentToken: "foxtrot",
|
||||
ACLAgentRecoveryToken: "golf",
|
||||
ACLReplicationToken: "hotel",
|
||||
ACLConfigFileRegistrationToken: "delta",
|
||||
ACLDefaultToken: "alpha",
|
||||
ACLAgentToken: "bravo",
|
||||
ACLAgentRecoveryToken: "charlie",
|
||||
ACLReplicationToken: "delta",
|
||||
ACLConfigFileRegistrationToken: "echo",
|
||||
ACLDNSToken: "foxtrot",
|
||||
}
|
||||
|
||||
tokens := `{
|
||||
"agent" : "india",
|
||||
"agent_recovery" : "juliett",
|
||||
"default": "kilo",
|
||||
"replication": "lima",
|
||||
"config_file_service_registration": "mike"
|
||||
"agent" : "golf",
|
||||
"agent_recovery" : "hotel",
|
||||
"default": "india",
|
||||
"replication": "juliet",
|
||||
"config_file_service_registration": "kilo",
|
||||
"dns": "lima"
|
||||
}`
|
||||
|
||||
require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600))
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
|
||||
// no updates since token persistence is not enabled
|
||||
require.Equal(t, "echo", store.UserToken())
|
||||
require.Equal(t, "foxtrot", store.AgentToken())
|
||||
require.Equal(t, "golf", store.AgentRecoveryToken())
|
||||
require.Equal(t, "hotel", store.ReplicationToken())
|
||||
require.Equal(t, "delta", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "alpha", store.UserToken())
|
||||
require.Equal(t, "bravo", store.AgentToken())
|
||||
require.Equal(t, "charlie", store.AgentRecoveryToken())
|
||||
require.Equal(t, "delta", store.ReplicationToken())
|
||||
require.Equal(t, "echo", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "foxtrot", store.DNSToken())
|
||||
|
||||
cfg.EnablePersistence = true
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
|
||||
require.Equal(t, "india", store.AgentToken())
|
||||
require.Equal(t, "juliett", store.AgentRecoveryToken())
|
||||
require.Equal(t, "kilo", store.UserToken())
|
||||
require.Equal(t, "lima", store.ReplicationToken())
|
||||
require.Equal(t, "mike", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "golf", store.AgentToken())
|
||||
require.Equal(t, "hotel", store.AgentRecoveryToken())
|
||||
require.Equal(t, "india", store.UserToken())
|
||||
require.Equal(t, "juliet", store.ReplicationToken())
|
||||
require.Equal(t, "kilo", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "lima", store.DNSToken())
|
||||
|
||||
// check store persistence was enabled
|
||||
require.NotNil(t, store.persistence)
|
||||
|
@ -115,7 +124,8 @@ func TestStore_Load(t *testing.T) {
|
|||
"agent_recovery" : "november",
|
||||
"default": "oscar",
|
||||
"replication" : "papa",
|
||||
"config_file_service_registration" : "lima"
|
||||
"config_file_service_registration" : "lima",
|
||||
"dns": "kilo"
|
||||
}`
|
||||
|
||||
cfg := Config{
|
||||
|
@ -126,6 +136,7 @@ func TestStore_Load(t *testing.T) {
|
|||
ACLAgentRecoveryToken: "sierra",
|
||||
ACLReplicationToken: "tango",
|
||||
ACLConfigFileRegistrationToken: "uniform",
|
||||
ACLDNSToken: "victor",
|
||||
}
|
||||
|
||||
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, "papa", store.ReplicationToken())
|
||||
require.Equal(t, "lima", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "kilo", store.DNSToken())
|
||||
})
|
||||
|
||||
t.Run("with some persisted tokens", func(t *testing.T) {
|
||||
tokens := `{
|
||||
"agent" : "uniform",
|
||||
"agent_recovery" : "victor"
|
||||
"agent" : "xray",
|
||||
"agent_recovery" : "zulu"
|
||||
}`
|
||||
|
||||
cfg := Config{
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "whiskey",
|
||||
ACLAgentToken: "xray",
|
||||
ACLAgentRecoveryToken: "yankee",
|
||||
ACLReplicationToken: "zulu",
|
||||
ACLConfigFileRegistrationToken: "victor",
|
||||
ACLDefaultToken: "alpha",
|
||||
ACLAgentToken: "bravo",
|
||||
ACLAgentRecoveryToken: "charlie",
|
||||
ACLReplicationToken: "delta",
|
||||
ACLConfigFileRegistrationToken: "echo",
|
||||
ACLDNSToken: "foxtrot",
|
||||
}
|
||||
|
||||
require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600))
|
||||
require.NoError(t, store.Load(cfg, logger))
|
||||
|
||||
require.Equal(t, "uniform", store.AgentToken())
|
||||
require.Equal(t, "victor", store.AgentRecoveryToken())
|
||||
require.Equal(t, "whiskey", store.UserToken())
|
||||
require.Equal(t, "zulu", store.ReplicationToken())
|
||||
require.Equal(t, "victor", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "xray", store.AgentToken())
|
||||
require.Equal(t, "zulu", store.AgentRecoveryToken())
|
||||
|
||||
require.Equal(t, "alpha", store.UserToken())
|
||||
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) {
|
||||
cfg := Config{
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "one",
|
||||
ACLAgentToken: "two",
|
||||
ACLAgentRecoveryToken: "three",
|
||||
ACLReplicationToken: "four",
|
||||
ACLConfigFileRegistrationToken: "five",
|
||||
ACLDefaultToken: "alpha",
|
||||
ACLAgentToken: "bravo",
|
||||
ACLAgentRecoveryToken: "charlie",
|
||||
ACLReplicationToken: "delta",
|
||||
ACLConfigFileRegistrationToken: "echo",
|
||||
ACLDNSToken: "foxtrot",
|
||||
}
|
||||
|
||||
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.Contains(t, err.Error(), "failed to decode tokens file")
|
||||
|
||||
require.Equal(t, "one", store.UserToken())
|
||||
require.Equal(t, "two", store.AgentToken())
|
||||
require.Equal(t, "three", store.AgentRecoveryToken())
|
||||
require.Equal(t, "four", store.ReplicationToken())
|
||||
require.Equal(t, "five", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "alpha", store.UserToken())
|
||||
require.Equal(t, "bravo", store.AgentToken())
|
||||
require.Equal(t, "charlie", store.AgentRecoveryToken())
|
||||
require.Equal(t, "delta", store.ReplicationToken())
|
||||
require.Equal(t, "echo", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "foxtrot", store.DNSToken())
|
||||
})
|
||||
|
||||
t.Run("persisted file contains invalid json", func(t *testing.T) {
|
||||
|
@ -194,8 +211,9 @@ func TestStore_Load(t *testing.T) {
|
|||
ACLDefaultToken: "alfa",
|
||||
ACLAgentToken: "bravo",
|
||||
ACLAgentRecoveryToken: "charlie",
|
||||
ACLReplicationToken: "foxtrot",
|
||||
ACLConfigFileRegistrationToken: "golf",
|
||||
ACLReplicationToken: "delta",
|
||||
ACLConfigFileRegistrationToken: "echo",
|
||||
ACLDNSToken: "foxtrot",
|
||||
}
|
||||
|
||||
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, "bravo", store.AgentToken())
|
||||
require.Equal(t, "charlie", store.AgentRecoveryToken())
|
||||
require.Equal(t, "foxtrot", store.ReplicationToken())
|
||||
require.Equal(t, "golf", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "delta", store.ReplicationToken())
|
||||
require.Equal(t, "echo", store.ConfigFileRegistrationToken())
|
||||
require.Equal(t, "foxtrot", store.DNSToken())
|
||||
})
|
||||
}
|
||||
|
||||
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) {
|
||||
dataDir := testutil.TempDir(t, "datadir")
|
||||
store := new(Store)
|
||||
cfg := Config{
|
||||
EnablePersistence: true,
|
||||
DataDir: dataDir,
|
||||
ACLDefaultToken: "default-token",
|
||||
ACLAgentToken: "agent-token",
|
||||
ACLAgentRecoveryToken: "recovery-token",
|
||||
ACLReplicationToken: "replication-token",
|
||||
ACLConfigFileRegistrationToken: "registration-token",
|
||||
ACLDefaultToken: "alpha",
|
||||
ACLAgentToken: "bravo",
|
||||
ACLAgentRecoveryToken: "charlie",
|
||||
ACLReplicationToken: "delta",
|
||||
ACLConfigFileRegistrationToken: "echo",
|
||||
ACLDNSToken: "foxtrot",
|
||||
}
|
||||
err := store.Load(cfg, hclog.New(nil))
|
||||
require.NoError(t, err)
|
||||
|
@ -240,37 +266,39 @@ func TestStore_WithPersistenceLock(t *testing.T) {
|
|||
t.Run("persist some tokens", func(t *testing.T) {
|
||||
dataDir, store := setupStore()
|
||||
err := store.WithPersistenceLock(func() error {
|
||||
require.True(t, store.UpdateUserToken("the-new-default-token", TokenSourceAPI))
|
||||
require.True(t, store.UpdateAgentRecoveryToken("the-new-recovery-token", TokenSourceAPI))
|
||||
require.True(t, store.UpdateUserToken("sierra", TokenSourceAPI))
|
||||
require.True(t, store.UpdateAgentRecoveryToken("tango", TokenSourceAPI))
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Only API-sourced tokens are persisted.
|
||||
requirePersistedTokens(t, dataDir, persistedTokens{
|
||||
Default: "the-new-default-token",
|
||||
AgentRecovery: "the-new-recovery-token",
|
||||
Default: "sierra",
|
||||
AgentRecovery: "tango",
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("persist all tokens", func(t *testing.T) {
|
||||
dataDir, store := setupStore()
|
||||
err := store.WithPersistenceLock(func() error {
|
||||
require.True(t, store.UpdateUserToken("the-new-default-token", TokenSourceAPI))
|
||||
require.True(t, store.UpdateAgentToken("the-new-agent-token", TokenSourceAPI))
|
||||
require.True(t, store.UpdateAgentRecoveryToken("the-new-recovery-token", TokenSourceAPI))
|
||||
require.True(t, store.UpdateReplicationToken("the-new-replication-token", TokenSourceAPI))
|
||||
require.True(t, store.UpdateConfigFileRegistrationToken("the-new-registration-token", TokenSourceAPI))
|
||||
require.True(t, store.UpdateUserToken("sierra", TokenSourceAPI))
|
||||
require.True(t, store.UpdateAgentToken("tango", TokenSourceAPI))
|
||||
require.True(t, store.UpdateAgentRecoveryToken("uniform", TokenSourceAPI))
|
||||
require.True(t, store.UpdateReplicationToken("victor", TokenSourceAPI))
|
||||
require.True(t, store.UpdateConfigFileRegistrationToken("xray", TokenSourceAPI))
|
||||
require.True(t, store.UpdateDNSToken("zulu", TokenSourceAPI))
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
requirePersistedTokens(t, dataDir, persistedTokens{
|
||||
Default: "the-new-default-token",
|
||||
Agent: "the-new-agent-token",
|
||||
AgentRecovery: "the-new-recovery-token",
|
||||
Replication: "the-new-replication-token",
|
||||
ConfigFileRegistration: "the-new-registration-token",
|
||||
Default: "sierra",
|
||||
Agent: "tango",
|
||||
AgentRecovery: "uniform",
|
||||
Replication: "victor",
|
||||
ConfigFileRegistration: "xray",
|
||||
DNS: "zulu",
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ const (
|
|||
TokenKindUser
|
||||
TokenKindReplication
|
||||
TokenKindConfigFileRegistration
|
||||
TokenKindDNS
|
||||
)
|
||||
|
||||
type watcher struct {
|
||||
|
@ -52,7 +53,7 @@ type Store struct {
|
|||
// also be used for agent operations if the agent token isn't set.
|
||||
userToken string
|
||||
|
||||
// userTokenSource indicates where this token originated from
|
||||
// userTokenSource indicates where this token originated from.
|
||||
userTokenSource TokenSource
|
||||
|
||||
// agentToken is used for internal agent operations like self-registering
|
||||
|
@ -60,7 +61,7 @@ type Store struct {
|
|||
// user-initiated operations.
|
||||
agentToken string
|
||||
|
||||
// agentTokenSource indicates where this token originated from
|
||||
// agentTokenSource indicates where this token originated from.
|
||||
agentTokenSource TokenSource
|
||||
|
||||
// agentRecoveryToken is a special token that's only used locally for
|
||||
|
@ -68,23 +69,30 @@ type Store struct {
|
|||
// available.
|
||||
agentRecoveryToken string
|
||||
|
||||
// agentRecoveryTokenSource indicates where this token originated from
|
||||
// agentRecoveryTokenSource indicates where this token originated from.
|
||||
agentRecoveryTokenSource TokenSource
|
||||
|
||||
// replicationToken is a special token that's used by servers to
|
||||
// replicate data from the primary datacenter.
|
||||
replicationToken string
|
||||
|
||||
// replicationTokenSource indicates where this token originated from
|
||||
// replicationTokenSource indicates where this token originated from.
|
||||
replicationTokenSource TokenSource
|
||||
|
||||
// configFileRegistrationToken is used to register services and checks
|
||||
// that are defined in configuration files.
|
||||
configFileRegistrationToken string
|
||||
|
||||
// configFileRegistrationTokenSource indicates where this token originated from
|
||||
// configFileRegistrationTokenSource indicates where this token originated from.
|
||||
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
|
||||
watcherIndex int
|
||||
|
||||
|
@ -204,6 +212,12 @@ func (t *Store) UpdateConfigFileRegistrationToken(token string, source TokenSour
|
|||
&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 {
|
||||
t.l.Lock()
|
||||
changed := *dstToken != token || *dstSource != source
|
||||
|
@ -261,6 +275,13 @@ func (t *Store) ConfigFileRegistrationToken() string {
|
|||
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.
|
||||
func (t *Store) UserTokenAndSource() (string, TokenSource) {
|
||||
t.l.RLock()
|
||||
|
@ -299,6 +320,14 @@ func (t *Store) ConfigFileRegistrationTokenAndSource() (string, TokenSource) {
|
|||
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.
|
||||
// This will never match an empty token for safety.
|
||||
func (t *Store) IsAgentRecoveryToken(token string) bool {
|
||||
|
|
|
@ -21,6 +21,8 @@ func TestStore_RegularTokens(t *testing.T) {
|
|||
replSource TokenSource
|
||||
registration string
|
||||
registrationSource TokenSource
|
||||
dns string
|
||||
dnsSource TokenSource
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
|
@ -95,11 +97,23 @@ func TestStore_RegularTokens(t *testing.T) {
|
|||
raw: tokens{registration: "G", registrationSource: TokenSourceAPI},
|
||||
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",
|
||||
set: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G"},
|
||||
raw: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G"},
|
||||
effective: 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", dns: "D"},
|
||||
effective: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G", dns: "D"},
|
||||
},
|
||||
}
|
||||
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))
|
||||
}
|
||||
|
||||
if tt.set.dns != "" {
|
||||
require.True(t, s.UpdateDNSToken(tt.set.dns, tt.set.dnsSource))
|
||||
}
|
||||
|
||||
// If they don't change then they return false.
|
||||
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.UpdateReplicationToken(tt.set.repl, tt.set.replSource))
|
||||
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.UpdateDNSToken(tt.set.dns, tt.set.dnsSource))
|
||||
|
||||
require.Equal(t, tt.effective.user, s.UserToken())
|
||||
require.Equal(t, tt.effective.agent, s.AgentToken())
|
||||
require.Equal(t, tt.effective.recovery, s.AgentRecoveryToken())
|
||||
require.Equal(t, tt.effective.repl, s.ReplicationToken())
|
||||
require.Equal(t, tt.effective.registration, s.ConfigFileRegistrationToken())
|
||||
require.Equal(t, tt.effective.dns, s.DNSToken())
|
||||
|
||||
tok, src := s.UserTokenAndSource()
|
||||
require.Equal(t, tt.raw.user, tok)
|
||||
|
@ -157,6 +177,10 @@ func TestStore_RegularTokens(t *testing.T) {
|
|||
tok, src = s.ConfigFileRegistrationTokenAndSource()
|
||||
require.Equal(t, tt.raw.registration, tok)
|
||||
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)
|
||||
replicationNotifier2 := newNotification(t, s, TokenKindReplication)
|
||||
registrationNotifier := newNotification(t, s, TokenKindConfigFileRegistration)
|
||||
dnsNotifier := newNotification(t, s, TokenKindDNS)
|
||||
|
||||
// perform an update of the user token
|
||||
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, replicationNotifier2.Ch)
|
||||
requireNotNotified(t, registrationNotifier.Ch)
|
||||
requireNotNotified(t, dnsNotifier.Ch)
|
||||
|
||||
// update the agent token which should send a notification to the agent notifier.
|
||||
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, replicationNotifier2.Ch)
|
||||
requireNotNotified(t, registrationNotifier.Ch)
|
||||
requireNotNotified(t, dnsNotifier.Ch)
|
||||
|
||||
// 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))
|
||||
|
@ -244,6 +271,7 @@ func TestStore_Notify(t *testing.T) {
|
|||
requireNotifiedOnce(t, agentRecoveryNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier2.Ch)
|
||||
requireNotNotified(t, registrationNotifier.Ch)
|
||||
requireNotNotified(t, dnsNotifier.Ch)
|
||||
|
||||
// update the replication token which should send a notification to the replication notifier.
|
||||
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)
|
||||
requireNotifiedOnce(t, replicationNotifier2.Ch)
|
||||
requireNotNotified(t, registrationNotifier.Ch)
|
||||
requireNotNotified(t, dnsNotifier.Ch)
|
||||
|
||||
s.StopNotify(replicationNotifier2)
|
||||
|
||||
|
@ -266,6 +295,7 @@ func TestStore_Notify(t *testing.T) {
|
|||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier2.Ch)
|
||||
requireNotNotified(t, registrationNotifier.Ch)
|
||||
requireNotNotified(t, dnsNotifier.Ch)
|
||||
|
||||
// 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))
|
||||
|
@ -276,6 +306,18 @@ func TestStore_Notify(t *testing.T) {
|
|||
requireNotNotified(t, agentRecoveryNotifier.Ch)
|
||||
requireNotNotified(t, replicationNotifier2.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
|
||||
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.UpdateReplicationToken("eb0b56b9-fa65-4ae1-902a-c64457c62ac6", 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
|
||||
requireNotNotified(t, agentNotifier.Ch)
|
||||
|
@ -290,4 +333,5 @@ func TestStore_Notify(t *testing.T) {
|
|||
requireNotNotified(t, replicationNotifier.Ch)
|
||||
requireNotNotified(t, agentRecoveryNotifier.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)
|
||||
}
|
||||
|
||||
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
|
||||
// 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.
|
||||
|
|
|
@ -1635,6 +1635,10 @@ func TestAPI_AgentUpdateToken(t *testing.T) {
|
|||
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) {
|
||||
|
@ -1723,6 +1727,9 @@ func TestAPI_AgentUpdateToken(t *testing.T) {
|
|||
|
||||
_, err = agent.UpdateConfigFileRegistrationToken("root", nil)
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = agent.UpdateDNSToken("root", nil)
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -8,9 +8,10 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
|
||||
"github.com/hashicorp/consul/command/flags"
|
||||
"github.com/hashicorp/consul/command/helpers"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func New(ui cli.Ui) *cmd {
|
||||
|
@ -63,6 +64,8 @@ func (c *cmd) Run(args []string) int {
|
|||
_, err = client.Agent().UpdateReplicationACLToken(token, nil)
|
||||
case "config_file_service_registration":
|
||||
_, err = client.Agent().UpdateConfigFileRegistrationToken(token, nil)
|
||||
case "dns":
|
||||
_, err = client.Agent().UpdateDNSToken(token, nil)
|
||||
default:
|
||||
c.UI.Error(fmt.Sprintf("Unknown token type"))
|
||||
return 1
|
||||
|
@ -140,6 +143,11 @@ Usage: consul acl set-agent-token [options] TYPE TOKEN
|
|||
If a service or check definition contains a 'token'
|
||||
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:
|
||||
|
||||
$ 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/sdk v0.14.1
|
||||
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/itchyny/gojq v0.12.13
|
||||
github.com/mitchellh/copystructure v1.2.0
|
||||
|
|
|
@ -14,7 +14,7 @@ require (
|
|||
github.com/hashicorp/consul/envoyextensions v0.4.1
|
||||
github.com/hashicorp/consul/proto-public v0.4.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-multierror v1.1.1
|
||||
github.com/hashicorp/go-uuid v1.0.3
|
||||
|
|
|
@ -114,7 +114,7 @@ func AssertUpstreamEndpointStatusWithClient(
|
|||
| length`,
|
||||
clusterName, healthStatus)
|
||||
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
|
||||
|
||||
result, err := strconv.Atoi(results[0])
|
||||
|
|
|
@ -614,6 +614,7 @@ func newContainerRequest(config Config, opts containerOpts, ports ...int) (podRe
|
|||
"8500/tcp", // Consul HTTP API
|
||||
"8501/tcp", // Consul HTTPs API
|
||||
"8502/tcp", // Consul gRPC API
|
||||
"8600/udp", // Consul DNS API
|
||||
|
||||
"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
|
||||
// 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.
|
||||
// - Create the peering, export the service from accepting cluster, and verify service
|
||||
// connectivity.
|
||||
|
@ -120,7 +120,7 @@ func BasicPeeringTwoClustersSetup(
|
|||
libassert.PeeringStatus(t, acceptingClient, AcceptingPeerName, api.PeeringStateActive)
|
||||
// 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
|
||||
{
|
||||
clientNode := acceptingCluster.Clients()[0]
|
||||
|
@ -144,7 +144,7 @@ func BasicPeeringTwoClustersSetup(
|
|||
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
|
||||
{
|
||||
clientNode := dialingCluster.Clients()[0]
|
||||
|
@ -268,11 +268,11 @@ func NewClusterWithConfig(
|
|||
}
|
||||
|
||||
// Add numClients static clients to register the service
|
||||
configbuiilder := libcluster.NewConfigBuilder(ctx).
|
||||
configBuilder := libcluster.NewConfigBuilder(ctx).
|
||||
Client().
|
||||
Peering(true).
|
||||
RetryJoin(retryJoin...)
|
||||
clientConf := configbuiilder.ToAgentConfig(t)
|
||||
clientConf := configBuilder.ToAgentConfig(t)
|
||||
t.Logf("%s client config: \n%s", opts.Datacenter, clientConf.JSON)
|
||||
if clientHclConfig != "" {
|
||||
clientConf.MutatebyAgentConfig(clientHclConfig)
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
|
||||
package topology
|
||||
|
||||
const DefaultDataplaneImage = "hashicorp/consul-dataplane:1.1.0"
|
||||
const DefaultDataplaneImage = "hashicorp/consul-dataplane:1.2.1"
|
||||
|
|
Loading…
Reference in New Issue