diff --git a/command/agent/acl_endpoint.go b/command/agent/acl_endpoint.go index a0e511a24..50d9f49e4 100644 --- a/command/agent/acl_endpoint.go +++ b/command/agent/acl_endpoint.go @@ -132,6 +132,27 @@ func (s *HTTPServer) ACLTokensRequest(resp http.ResponseWriter, req *http.Reques return out.Tokens, nil } +func (s *HTTPServer) ACLTokenBootstrap(resp http.ResponseWriter, req *http.Request) (interface{}, error) { + // Ensure this is a PUT or POST + if !(req.Method == "PUT" || req.Method == "POST") { + return nil, CodedError(405, ErrInvalidMethod) + } + + // Format the request + args := structs.ACLTokenBootstrapRequest{} + s.parseRegion(req, &args.Region) + + var out structs.ACLTokenUpsertResponse + if err := s.agent.RPC("ACL.Bootstrap", &args, &out); err != nil { + return nil, err + } + setIndex(resp, out.Index) + if len(out.Tokens) > 0 { + return out.Tokens[0], nil + } + return nil, nil +} + func (s *HTTPServer) ACLTokenSpecificRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { accessor := strings.TrimPrefix(req.URL.Path, "/v1/acl/token") diff --git a/command/agent/acl_endpoint_test.go b/command/agent/acl_endpoint_test.go index bd5496317..6bb66a753 100644 --- a/command/agent/acl_endpoint_test.go +++ b/command/agent/acl_endpoint_test.go @@ -174,6 +174,34 @@ func TestHTTP_ACLPolicyDelete(t *testing.T) { }) } +func TestHTTP_ACLTokenBootstrap(t *testing.T) { + t.Parallel() + httpTest(t, nil, func(s *TestAgent) { + // Make the HTTP request + req, err := http.NewRequest("PUT", "/v1/acl/bootstrap", nil) + if err != nil { + t.Fatalf("err: %v", err) + } + respW := httptest.NewRecorder() + + // Make the request + obj, err := s.Server.ACLTokenBootstrap(respW, req) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Check for the index + if respW.HeaderMap.Get("X-Nomad-Index") == "" { + t.Fatalf("missing index") + } + + // Check the output + n := obj.(*structs.ACLToken) + assert.NotNil(t, n) + assert.Equal(t, "Bootstrap Token", n.Name) + }) +} + func TestHTTP_ACLTokenList(t *testing.T) { t.Parallel() httpTest(t, nil, func(s *TestAgent) { diff --git a/command/agent/config_test.go b/command/agent/config_test.go index 878f89f6e..ed84c6dfe 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -104,8 +104,8 @@ func TestConfig_Merge(t *testing.T) { }, ACL: &ACLConfig{ Enabled: true, - TokenTTL: "60s", - PolicyTTL: "60s", + TokenTTL: 60 * time.Second, + PolicyTTL: 60 * time.Second, }, Ports: &Ports{ HTTP: 4646, @@ -248,8 +248,8 @@ func TestConfig_Merge(t *testing.T) { }, ACL: &ACLConfig{ Enabled: true, - TokenTTL: "20s", - PolicyTTL: "20s", + TokenTTL: 20 * time.Second, + PolicyTTL: 20 * time.Second, }, Ports: &Ports{ HTTP: 20000, diff --git a/command/agent/http.go b/command/agent/http.go index 0efbfe818..13624d283 100644 --- a/command/agent/http.go +++ b/command/agent/http.go @@ -151,6 +151,7 @@ func (s *HTTPServer) registerHandlers(enableDebug bool) { s.mux.HandleFunc("/v1/acl/policies", s.wrap(s.ACLPoliciesRequest)) s.mux.HandleFunc("/v1/acl/policy/", s.wrap(s.ACLPolicySpecificRequest)) + s.mux.HandleFunc("/v1/acl/bootstrap", s.wrap(s.ACLTokenBootstrap)) s.mux.HandleFunc("/v1/acl/tokens", s.wrap(s.ACLTokensRequest)) s.mux.HandleFunc("/v1/acl/token", s.wrap(s.ACLTokenSpecificRequest))