Skip to content

Commit

Permalink
testutil: add ACL bootstrapping to test server configuration (#18811)
Browse files Browse the repository at this point in the history
Some of our `api` package tests have ACLs enabled, but none of those tests also
run clients and the "wait for the clients to be live" code reads from the Node
API. The caller can't bootstrap ACLs until `NewTestServer` returns, and this
makes for a circular dependency.

Allow developers to provide a bootstrap token to the test server config, and
if it's available, have the server bootstrap the ACL system with it before
checking for live clients.
  • Loading branch information
tgross authored Oct 19, 2023
1 parent 8372074 commit f5c5035
Showing 1 changed file with 37 additions and 2 deletions.
39 changes: 37 additions & 2 deletions testutil/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ type VaultConfig struct {

// ACLConfig is used to configure ACLs
type ACLConfig struct {
Enabled bool `json:"enabled"`
Enabled bool `json:"enabled"`
BootstrapToken string `json:"-"` // not in the real config
}

// ServerConfigCallback is a function interface which can be
Expand Down Expand Up @@ -195,6 +196,7 @@ func NewTestServer(t testing.T, cb ServerConfigCallback) *TestServer {
if nomadConfig.Stderr != nil {
stderr = nomadConfig.Stderr
}
t.Logf("CONFIG JSON: %s", string(configContent))

args := []string{"agent", "-config", configFile.Name()}
if nomadConfig.DevMode {
Expand Down Expand Up @@ -228,6 +230,10 @@ func NewTestServer(t testing.T, cb ServerConfigCallback) *TestServer {
server.waitForAPI()
}

if nomadConfig.ACL.Enabled && nomadConfig.ACL.BootstrapToken != "" {
server.bootstrapSelf()
}

// Wait for the client to be ready
if nomadConfig.DevMode {
server.waitForClient()
Expand Down Expand Up @@ -272,6 +278,28 @@ func (s *TestServer) Stop() {

}

// bootstrapSelf bootstraps the ACL system from the provided token.
func (s *TestServer) bootstrapSelf() {

contentType := "application/json"

rootToken := s.Config.ACL.BootstrapToken
body := struct{ BootstrapSecret string }{rootToken}
buf, err := json.Marshal(body)
if err != nil {
s.t.Fatalf("err: %s", err)
}

resp, err := s.HTTPClient.Post(s.url("/v1/acl/bootstrap"), contentType, bytes.NewBuffer(buf))
if err != nil {
s.t.Fatalf("err: %s", err)
}
defer resp.Body.Close()
if err := s.requireOK(resp); err != nil {
s.t.Fatalf("err: %s", err)
}
}

// waitForAPI waits for only the agent HTTP endpoint to start
// responding. This is an indication that the agent has started,
// but will likely return before a leader is elected.
Expand Down Expand Up @@ -324,7 +352,14 @@ func (s *TestServer) waitForClient() {
}

WaitForResult(func() (bool, error) {
resp, err := s.HTTPClient.Get(s.url("/v1/nodes"))
req, err := http.NewRequest(http.MethodGet, s.url("/v1/nodes"), nil)
if err != nil {
return false, err
}
if s.Config.ACL.BootstrapToken != "" {
req.Header.Set("X-Nomad-Token", s.Config.ACL.BootstrapToken)
}
resp, err := s.HTTPClient.Do(req)
if err != nil {
return false, err
}
Expand Down

0 comments on commit f5c5035

Please sign in to comment.