github.com/hernad/nomad@v1.6.112/command/operator_raft_list.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package command
     5  
     6  import (
     7  	"fmt"
     8  	"sort"
     9  	"strings"
    10  
    11  	"github.com/hernad/nomad/api"
    12  	"github.com/posener/complete"
    13  	"github.com/ryanuber/columnize"
    14  )
    15  
    16  type OperatorRaftListCommand struct {
    17  	Meta
    18  }
    19  
    20  func (c *OperatorRaftListCommand) Help() string {
    21  	helpText := `
    22  Usage: nomad operator raft list-peers [options]
    23  
    24    Displays the current Raft peer configuration.
    25  
    26    If ACLs are enabled, this command requires a management token.
    27  
    28  General Options:
    29  
    30    ` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace) + `
    31  
    32  List Peers Options:
    33  
    34    -stale=[true|false]
    35      The -stale argument defaults to "false" which means the leader provides the
    36      result. If the cluster is in an outage state without a leader, you may need
    37      to set -stale to "true" to get the configuration from a non-leader server.
    38  `
    39  	return strings.TrimSpace(helpText)
    40  }
    41  
    42  func (c *OperatorRaftListCommand) AutocompleteFlags() complete.Flags {
    43  	return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
    44  		complete.Flags{
    45  			"-stale": complete.PredictAnything,
    46  		})
    47  }
    48  
    49  func (c *OperatorRaftListCommand) AutocompleteArgs() complete.Predictor {
    50  	return complete.PredictNothing
    51  }
    52  
    53  func (c *OperatorRaftListCommand) Synopsis() string {
    54  	return "Display the current Raft peer configuration"
    55  }
    56  
    57  func (c *OperatorRaftListCommand) Name() string { return "operator raft list-peers" }
    58  
    59  func (c *OperatorRaftListCommand) Run(args []string) int {
    60  	var stale bool
    61  
    62  	flags := c.Meta.FlagSet("raft", FlagSetClient)
    63  	flags.Usage = func() { c.Ui.Output(c.Help()) }
    64  
    65  	flags.BoolVar(&stale, "stale", false, "")
    66  	if err := flags.Parse(args); err != nil {
    67  		c.Ui.Error(fmt.Sprintf("Failed to parse args: %v", err))
    68  		return 1
    69  	}
    70  
    71  	// Set up a client.
    72  	client, err := c.Meta.Client()
    73  	if err != nil {
    74  		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
    75  		return 1
    76  	}
    77  	operator := client.Operator()
    78  
    79  	// Fetch the current configuration.
    80  	q := &api.QueryOptions{
    81  		AllowStale: stale,
    82  	}
    83  	reply, err := operator.RaftGetConfiguration(q)
    84  	if err != nil {
    85  		c.Ui.Error(fmt.Sprintf("Failed to retrieve raft configuration: %v", err))
    86  		return 1
    87  	}
    88  
    89  	// Format it as a nice table.
    90  	result := []string{"Node|ID|Address|State|Voter|RaftProtocol"}
    91  	sort.Slice(reply.Servers, func(i, j int) bool {
    92  		return reply.Servers[i].Node < reply.Servers[j].Node
    93  	})
    94  
    95  	for _, s := range reply.Servers {
    96  		state := "follower"
    97  		if s.Leader {
    98  			state = "leader"
    99  		}
   100  		result = append(result, fmt.Sprintf("%s|%s|%s|%s|%v|%s",
   101  			s.Node, s.ID, s.Address, state, s.Voter, s.RaftProtocol))
   102  	}
   103  	c.Ui.Output(columnize.SimpleFormat(result))
   104  
   105  	return 0
   106  }