Passthrough replication token for token/policy replication
This commit is contained in:
parent
855240b1b5
commit
3e46094cee
|
@ -146,6 +146,9 @@ func convertServerConfig(agentConfig *Config, logOutput io.Writer) (*nomad.Confi
|
|||
if agentConfig.ACL.Enabled {
|
||||
conf.ACLEnabled = true
|
||||
}
|
||||
if agentConfig.ACL.ReplicationToken != "" {
|
||||
conf.ReplicationToken = agentConfig.ACL.ReplicationToken
|
||||
}
|
||||
|
||||
// Set up the bind addresses
|
||||
rpcAddr, err := net.ResolveTCPAddr("tcp", agentConfig.normalizedAddrs.RPC)
|
||||
|
|
|
@ -87,6 +87,7 @@ acl {
|
|||
enabled = true
|
||||
token_ttl = "60s"
|
||||
policy_ttl = "60s"
|
||||
replication_token = "foobar"
|
||||
}
|
||||
telemetry {
|
||||
statsite_address = "127.0.0.1:1234"
|
||||
|
|
|
@ -247,6 +247,11 @@ type ACLConfig struct {
|
|||
// to "30s". Reducing this impacts performance by forcing more
|
||||
// frequent resolution.
|
||||
PolicyTTL time.Duration `mapstructure:"policy_ttl"`
|
||||
|
||||
// ReplicationToken is used by servers to replicate tokens and policies
|
||||
// from the authoritative region. This must be a valid management token
|
||||
// within the authoritative region.
|
||||
ReplicationToken string `mapstructure:"replication_token"`
|
||||
}
|
||||
|
||||
// ServerConfig is configuration specific to the server mode
|
||||
|
@ -953,6 +958,9 @@ func (a *ACLConfig) Merge(b *ACLConfig) *ACLConfig {
|
|||
if b.PolicyTTL != 0 {
|
||||
result.PolicyTTL = b.PolicyTTL
|
||||
}
|
||||
if b.ReplicationToken != "" {
|
||||
result.ReplicationToken = b.ReplicationToken
|
||||
}
|
||||
return &result
|
||||
}
|
||||
|
||||
|
|
|
@ -573,6 +573,7 @@ func parseACL(result **ACLConfig, list *ast.ObjectList) error {
|
|||
"enabled",
|
||||
"token_ttl",
|
||||
"policy_ttl",
|
||||
"replication_token",
|
||||
}
|
||||
if err := checkHCLKeys(listVal, valid); err != nil {
|
||||
return err
|
||||
|
|
|
@ -105,9 +105,10 @@ func TestConfig_Parse(t *testing.T) {
|
|||
EncryptKey: "abc",
|
||||
},
|
||||
ACL: &ACLConfig{
|
||||
Enabled: true,
|
||||
TokenTTL: 60 * time.Second,
|
||||
PolicyTTL: 60 * time.Second,
|
||||
Enabled: true,
|
||||
TokenTTL: 60 * time.Second,
|
||||
PolicyTTL: 60 * time.Second,
|
||||
ReplicationToken: "foobar",
|
||||
},
|
||||
Telemetry: &Telemetry{
|
||||
StatsiteAddr: "127.0.0.1:1234",
|
||||
|
|
|
@ -103,9 +103,10 @@ func TestConfig_Merge(t *testing.T) {
|
|||
MaxHeartbeatsPerSecond: 30.0,
|
||||
},
|
||||
ACL: &ACLConfig{
|
||||
Enabled: true,
|
||||
TokenTTL: 60 * time.Second,
|
||||
PolicyTTL: 60 * time.Second,
|
||||
Enabled: true,
|
||||
TokenTTL: 60 * time.Second,
|
||||
PolicyTTL: 60 * time.Second,
|
||||
ReplicationToken: "foo",
|
||||
},
|
||||
Ports: &Ports{
|
||||
HTTP: 4646,
|
||||
|
@ -247,9 +248,10 @@ func TestConfig_Merge(t *testing.T) {
|
|||
retryInterval: time.Second * 10,
|
||||
},
|
||||
ACL: &ACLConfig{
|
||||
Enabled: true,
|
||||
TokenTTL: 20 * time.Second,
|
||||
PolicyTTL: 20 * time.Second,
|
||||
Enabled: true,
|
||||
TokenTTL: 20 * time.Second,
|
||||
PolicyTTL: 20 * time.Second,
|
||||
ReplicationToken: "foobar",
|
||||
},
|
||||
Ports: &Ports{
|
||||
HTTP: 20000,
|
||||
|
|
|
@ -235,6 +235,10 @@ type Config struct {
|
|||
// ReplicationBackoff is how much we backoff when replication errors.
|
||||
// This is a tunable knob for testing primarily.
|
||||
ReplicationBackoff time.Duration
|
||||
|
||||
// ReplicationToken is the ACL Token Secret ID used to fetch from
|
||||
// the Authoritative Region.
|
||||
ReplicationToken string
|
||||
}
|
||||
|
||||
// CheckVersion is used to check if the ProtocolVersion is valid
|
||||
|
|
|
@ -691,6 +691,7 @@ START:
|
|||
|
||||
// Fetch the list of policies
|
||||
var resp structs.ACLPolicyListResponse
|
||||
req.SecretID = s.ReplicationToken()
|
||||
err := s.forwardRegion(s.config.AuthoritativeRegion,
|
||||
"ACL.ListPolicies", &req, &resp)
|
||||
if err != nil {
|
||||
|
@ -719,7 +720,8 @@ START:
|
|||
req := structs.ACLPolicySetRequest{
|
||||
Names: update,
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Region: s.config.AuthoritativeRegion,
|
||||
Region: s.config.AuthoritativeRegion,
|
||||
SecretID: s.ReplicationToken(),
|
||||
},
|
||||
}
|
||||
var reply structs.ACLPolicySetResponse
|
||||
|
@ -831,6 +833,7 @@ START:
|
|||
|
||||
// Fetch the list of tokens
|
||||
var resp structs.ACLTokenListResponse
|
||||
req.SecretID = s.ReplicationToken()
|
||||
err := s.forwardRegion(s.config.AuthoritativeRegion,
|
||||
"ACL.ListTokens", &req, &resp)
|
||||
if err != nil {
|
||||
|
@ -859,7 +862,8 @@ START:
|
|||
req := structs.ACLTokenSetRequest{
|
||||
AccessorIDS: update,
|
||||
QueryOptions: structs.QueryOptions{
|
||||
Region: s.config.AuthoritativeRegion,
|
||||
Region: s.config.AuthoritativeRegion,
|
||||
SecretID: s.ReplicationToken(),
|
||||
},
|
||||
}
|
||||
var reply structs.ACLTokenSetResponse
|
||||
|
|
|
@ -629,17 +629,18 @@ func TestLeader_RestoreVaultAccessors(t *testing.T) {
|
|||
|
||||
func TestLeader_ReplicateACLPolicies(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, func(c *Config) {
|
||||
s1, root := testACLServer(t, func(c *Config) {
|
||||
c.Region = "region1"
|
||||
c.AuthoritativeRegion = "region1"
|
||||
c.ACLEnabled = true
|
||||
})
|
||||
defer s1.Shutdown()
|
||||
s2 := testServer(t, func(c *Config) {
|
||||
s2, _ := testACLServer(t, func(c *Config) {
|
||||
c.Region = "region2"
|
||||
c.AuthoritativeRegion = "region1"
|
||||
c.ACLEnabled = true
|
||||
c.ReplicationBackoff = 20 * time.Millisecond
|
||||
c.ReplicationToken = root.SecretID
|
||||
})
|
||||
defer s2.Shutdown()
|
||||
testJoin(t, s1, s2)
|
||||
|
@ -699,17 +700,18 @@ func TestLeader_DiffACLPolicies(t *testing.T) {
|
|||
|
||||
func TestLeader_ReplicateACLTokens(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, func(c *Config) {
|
||||
s1, root := testACLServer(t, func(c *Config) {
|
||||
c.Region = "region1"
|
||||
c.AuthoritativeRegion = "region1"
|
||||
c.ACLEnabled = true
|
||||
})
|
||||
defer s1.Shutdown()
|
||||
s2 := testServer(t, func(c *Config) {
|
||||
s2, _ := testACLServer(t, func(c *Config) {
|
||||
c.Region = "region2"
|
||||
c.AuthoritativeRegion = "region1"
|
||||
c.ACLEnabled = true
|
||||
c.ReplicationBackoff = 20 * time.Millisecond
|
||||
c.ReplicationToken = root.SecretID
|
||||
})
|
||||
defer s2.Shutdown()
|
||||
testJoin(t, s1, s2)
|
||||
|
|
|
@ -1147,6 +1147,12 @@ func (s *Server) GetConfig() *Config {
|
|||
return s.config
|
||||
}
|
||||
|
||||
// ReplicationToken returns the token used for replication. We use a method to support
|
||||
// dynamic reloading of this value later.
|
||||
func (s *Server) ReplicationToken() string {
|
||||
return s.config.ReplicationToken
|
||||
}
|
||||
|
||||
// peersInfoContent is used to help operators understand what happened to the
|
||||
// peers.json file. This is written to a file called peers.info in the same
|
||||
// location.
|
||||
|
|
Loading…
Reference in New Issue