mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
The Nomad client will have its identity renewed according to the TTL which defaults to 24h. In certain situations such as root keyring rotation, operators may want to force clients to renew their identities before the TTL threshold is met. This change introduces a client HTTP and RPC endpoint which will instruct the node to request a new identity at its next heartbeat. This can be used via the API or a new command. While this is a manual intervention step on top of the any keyring rotation, it dramatically reduces the initial feature complexity as it provides an asynchronous and efficient method of renewal that utilises existing functionality.
89 lines
1.9 KiB
Go
89 lines
1.9 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package command
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/nomad/api"
|
|
"github.com/posener/complete"
|
|
)
|
|
|
|
type NodeIdentityRenewCommand struct {
|
|
Meta
|
|
}
|
|
|
|
func (n *NodeIdentityRenewCommand) Help() string {
|
|
helpText := `
|
|
Usage: nomad node identity renew [options] <node_id>
|
|
|
|
Instruct a node to renew its identity at the next heartbeat. This command only
|
|
applies to client agents.
|
|
|
|
General Options:
|
|
|
|
` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace)
|
|
|
|
return strings.TrimSpace(helpText)
|
|
}
|
|
|
|
func (n *NodeIdentityRenewCommand) Synopsis() string { return "Force a node to renew its identity" }
|
|
|
|
func (n *NodeIdentityRenewCommand) Name() string { return "node identity renew" }
|
|
|
|
func (n *NodeIdentityRenewCommand) Run(args []string) int {
|
|
|
|
flags := n.Meta.FlagSet(n.Name(), FlagSetClient)
|
|
flags.Usage = func() { n.Ui.Output(n.Help()) }
|
|
|
|
if err := flags.Parse(args); err != nil {
|
|
return 1
|
|
}
|
|
args = flags.Args()
|
|
|
|
if len(args) != 1 {
|
|
n.Ui.Error("This command takes one argument: <node_id>")
|
|
n.Ui.Error(commandErrorText(n))
|
|
return 1
|
|
}
|
|
|
|
// Get the HTTP client
|
|
client, err := n.Meta.Client()
|
|
if err != nil {
|
|
n.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
|
|
return 1
|
|
}
|
|
|
|
nodeID := args[0]
|
|
|
|
// Lookup nodeID
|
|
if nodeID != "" {
|
|
nodeID, err = lookupNodeID(client.Nodes(), nodeID)
|
|
if err != nil {
|
|
n.Ui.Error(err.Error())
|
|
return 1
|
|
}
|
|
}
|
|
|
|
req := api.NodeIdentityRenewRequest{
|
|
NodeID: nodeID,
|
|
}
|
|
|
|
if _, err := client.Nodes().Identity().Renew(&req, nil); err != nil {
|
|
n.Ui.Error(fmt.Sprintf("Error requesting node identity renewal: %s", err))
|
|
return 1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
func (n *NodeIdentityRenewCommand) AutocompleteFlags() complete.Flags {
|
|
return n.Meta.AutocompleteFlags(FlagSetClient)
|
|
}
|
|
|
|
func (n *NodeIdentityRenewCommand) AutocompleteArgs() complete.Predictor {
|
|
return nodePredictor(n.Client, nil)
|
|
}
|