Add CLI and API components for creating node introduction tokens via ACL endpoint. (#26332)

This commit is contained in:
James Rasell
2025-07-25 14:28:45 +02:00
committed by GitHub
parent 842f316615
commit 20251b675d
7 changed files with 406 additions and 0 deletions

View File

@@ -1246,3 +1246,54 @@ type ACLLoginRequest struct {
// LoginToken is the token used to login. This is a required parameter.
LoginToken string
}
// ACLIdentity is used to query the ACL identity endpoints.
type ACLIdentity struct {
client *Client
}
// ACLIdentity returns a new handle on the ACL identity API client.
func (c *Client) ACLIdentity() *ACLIdentity {
return &ACLIdentity{client: c}
}
// CreateClientIntroductionToken is the API endpoint used to generate a JWT
// token to be used for introducing a new client node into the cluster.
func (a *ACLIdentity) CreateClientIntroductionToken(
req *ACLIdentityClientIntroductionTokenRequest,
writeOpts *WriteOptions) (*ACLIdentityClientIntroductionTokenResponse, *WriteMeta, error) {
var resp ACLIdentityClientIntroductionTokenResponse
wm, err := a.client.put("/v1/acl/identity/client-introduction-token", req, &resp, writeOpts)
if err != nil {
return nil, nil, err
}
return &resp, wm, nil
}
// ACLIdentityClientIntroductionTokenRequest is the request object used within
// the ACL client introduction API request. This is used to generate a JWT token
// that can be used to register a new client node into the cluster.
type ACLIdentityClientIntroductionTokenRequest struct {
// TTL is the requested TTL for the identity token. This is an optional
// parameter and if not set, defaults to the server defined default TTL.
TTL time.Duration
// NodeName is the name of the node that is being introduced. This is added
// to the token as a claim when present, but is optional.
NodeName string
// NodePool is the name of the node pool that this node belongs to. This is
// an optional parameter, and if not set, defaults to "default".
NodePool string
}
// ACLIdentityClientIntroductionTokenResponse is the response object used within
// the ACL client introduction HTTP endpoint.
type ACLIdentityClientIntroductionTokenResponse struct {
// JWT is the signed identity token that can be used as an introduction
// token for a new client node to register with the Nomad cluster.
JWT string
}

View File

@@ -742,3 +742,38 @@ func TestACLBindingRules(t *testing.T) {
must.Len(t, 0, aclBindingRulesListResp)
assertQueryMeta(t, queryMeta)
}
// TestACLIdentity_CreateClientIntroductionToken perform some basic tests of the
// CreateClientIntroductionToken method. It does not test that the response
// contains a valid JWT, as that would require bringing in the JWT library into
// the API. Instead, we rely on HTTP and RPC tests to ensure that.
func TestACLIdentity_CreateClientIntroductionToken(t *testing.T) {
testutil.Parallel(t)
testClient, testServer, _ := makeACLClient(t, nil, nil)
defer testServer.Stop()
t.Run("empty_req_params", func(t *testing.T) {
req := ACLIdentityClientIntroductionTokenRequest{}
resp, _, err := testClient.ACLIdentity().CreateClientIntroductionToken(&req, nil)
must.NoError(t, err)
must.NotNil(t, resp)
must.NotEq(t, "", resp.JWT)
})
t.Run("full_req_params", func(t *testing.T) {
req := ACLIdentityClientIntroductionTokenRequest{
TTL: time.Second,
NodePool: NodePoolDefault,
NodeName: "test-node",
}
resp, _, err := testClient.ACLIdentity().CreateClientIntroductionToken(&req, nil)
must.NoError(t, err)
must.NotNil(t, resp)
must.NotEq(t, "", resp.JWT)
})
}