Merge pull request #2726 from hashicorp/f-cli-rework-3
Centralize command-line parsing part 3
This commit is contained in:
commit
5be21e3e24
|
@ -58,6 +58,14 @@ func (c *Command) HTTPClient() (*api.Client, error) {
|
|||
return api.NewClient(config)
|
||||
}
|
||||
|
||||
func (c *Command) HTTPAddr() string {
|
||||
return c.httpAddr.String()
|
||||
}
|
||||
|
||||
func (c *Command) HTTPToken() string {
|
||||
return c.token.String()
|
||||
}
|
||||
|
||||
func (c *Command) HTTPDatacenter() string {
|
||||
return c.datacenter.String()
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@ package command
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/mitchellh/cli"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testJoinCommand(t *testing.T) (*cli.MockUi, *JoinCommand) {
|
||||
|
|
|
@ -1,53 +1,47 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LeaveCommand is a Command implementation that instructs
|
||||
// the Consul agent to gracefully leave the cluster
|
||||
type LeaveCommand struct {
|
||||
Ui cli.Ui
|
||||
base.Command
|
||||
}
|
||||
|
||||
func (c *LeaveCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: consul leave
|
||||
Usage: consul leave [options]
|
||||
|
||||
Causes the agent to gracefully leave the Consul cluster and shutdown.
|
||||
|
||||
Options:
|
||||
` + c.Command.Help()
|
||||
|
||||
-rpc-addr=127.0.0.1:8400 RPC address of the Consul agent.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *LeaveCommand) Run(args []string) int {
|
||||
cmdFlags := flag.NewFlagSet("leave", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
rpcAddr := RPCAddrFlag(cmdFlags)
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
f := c.Command.NewFlagSet(c)
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
nonFlagArgs := cmdFlags.Args()
|
||||
nonFlagArgs := f.Args()
|
||||
if len(nonFlagArgs) > 0 {
|
||||
c.Ui.Error(fmt.Sprintf("Error found unexpected args: %v", nonFlagArgs))
|
||||
c.Ui.Output(c.Help())
|
||||
return 1
|
||||
}
|
||||
|
||||
client, err := RPCClient(*rpcAddr)
|
||||
client, err := c.Command.HTTPClient()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
|
||||
return 1
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
if err := client.Leave(); err != nil {
|
||||
if err := client.Agent().Leave(); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error leaving: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
|
|
@ -1,11 +1,22 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/mitchellh/cli"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testLeaveCommand(t *testing.T) (*cli.MockUi, *LeaveCommand) {
|
||||
ui := new(cli.MockUi)
|
||||
return ui, &LeaveCommand{
|
||||
Command: base.Command{
|
||||
Ui: ui,
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestLeaveCommand_implements(t *testing.T) {
|
||||
var _ cli.Command = &LeaveCommand{}
|
||||
}
|
||||
|
@ -14,9 +25,8 @@ func TestLeaveCommandRun(t *testing.T) {
|
|||
a1 := testAgent(t)
|
||||
defer a1.Shutdown()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &LeaveCommand{Ui: ui}
|
||||
args := []string{"-rpc-addr=" + a1.addr}
|
||||
ui, c := testLeaveCommand(t)
|
||||
args := []string{"-http-addr=" + a1.httpAddr}
|
||||
|
||||
code := c.Run(args)
|
||||
if code != 0 {
|
||||
|
@ -32,9 +42,8 @@ func TestLeaveCommandFailOnNonFlagArgs(t *testing.T) {
|
|||
a1 := testAgent(t)
|
||||
defer a1.Shutdown()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &LeaveCommand{Ui: ui}
|
||||
args := []string{"-rpc-addr=" + a1.addr, "appserver1"}
|
||||
_, c := testLeaveCommand(t)
|
||||
args := []string{"-http-addr=" + a1.httpAddr, "appserver1"}
|
||||
|
||||
code := c.Run(args)
|
||||
if code == 0 {
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
)
|
||||
|
||||
// MaintCommand is a Command implementation that enables or disables
|
||||
// node or service maintenance mode.
|
||||
type MaintCommand struct {
|
||||
Ui cli.Ui
|
||||
base.Command
|
||||
}
|
||||
|
||||
func (c *MaintCommand) Help() string {
|
||||
|
@ -40,15 +38,8 @@ Usage: consul maint [options]
|
|||
If no arguments are given, the agent's maintenance status will be shown.
|
||||
This will return blank if nothing is currently under maintenance.
|
||||
|
||||
Options:
|
||||
` + c.Command.Help()
|
||||
|
||||
-enable Enable maintenance mode.
|
||||
-disable Disable maintenance mode.
|
||||
-reason=<string> Text string describing the maintenance reason
|
||||
-service=<serviceID> Control maintenance mode for a specific service ID
|
||||
-token="" ACL token to use. Defaults to that of agent.
|
||||
-http-addr=127.0.0.1:8500 HTTP address of the Consul agent.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
|
@ -57,19 +48,15 @@ func (c *MaintCommand) Run(args []string) int {
|
|||
var disable bool
|
||||
var reason string
|
||||
var serviceID string
|
||||
var token string
|
||||
|
||||
cmdFlags := flag.NewFlagSet("maint", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
f := c.Command.NewFlagSet(c)
|
||||
|
||||
cmdFlags.BoolVar(&enable, "enable", false, "enable maintenance mode")
|
||||
cmdFlags.BoolVar(&disable, "disable", false, "disable maintenance mode")
|
||||
cmdFlags.StringVar(&reason, "reason", "", "maintenance reason")
|
||||
cmdFlags.StringVar(&serviceID, "service", "", "service maintenance")
|
||||
cmdFlags.StringVar(&token, "token", "", "")
|
||||
httpAddr := HTTPAddrFlag(cmdFlags)
|
||||
f.BoolVar(&enable, "enable", false, "Enable maintenance mode.")
|
||||
f.BoolVar(&disable, "disable", false, "Disable maintenance mode.")
|
||||
f.StringVar(&reason, "reason", "", "Text describing the maintenance reason.")
|
||||
f.StringVar(&serviceID, "service", "", "Control maintenance mode for a specific service ID.")
|
||||
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
|
@ -88,10 +75,7 @@ func (c *MaintCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Create and test the HTTP client
|
||||
conf := api.DefaultConfig()
|
||||
conf.Address = *httpAddr
|
||||
conf.Token = token
|
||||
client, err := api.NewClient(conf)
|
||||
client, err := c.Command.HTTPClient()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
|
||||
return 1
|
||||
|
|
|
@ -4,17 +4,27 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/hashicorp/consul/consul/structs"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testMaintCommand(t *testing.T) (*cli.MockUi, *MaintCommand) {
|
||||
ui := new(cli.MockUi)
|
||||
return ui, &MaintCommand{
|
||||
Command: base.Command{
|
||||
Ui: ui,
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestMaintCommand_implements(t *testing.T) {
|
||||
var _ cli.Command = &MaintCommand{}
|
||||
}
|
||||
|
||||
func TestMaintCommandRun_ConflictingArgs(t *testing.T) {
|
||||
ui := new(cli.MockUi)
|
||||
c := &MaintCommand{Ui: ui}
|
||||
_, c := testMaintCommand(t)
|
||||
|
||||
if code := c.Run([]string{"-enable", "-disable"}); code != 1 {
|
||||
t.Fatalf("expected return code 1, got %d", code)
|
||||
|
@ -53,8 +63,7 @@ func TestMaintCommandRun_NoArgs(t *testing.T) {
|
|||
a1.agent.EnableNodeMaintenance("broken 2", "")
|
||||
|
||||
// Run consul maint with no args (list mode)
|
||||
ui := new(cli.MockUi)
|
||||
c := &MaintCommand{Ui: ui}
|
||||
ui, c := testMaintCommand(t)
|
||||
|
||||
args := []string{"-http-addr=" + a1.httpAddr}
|
||||
code := c.Run(args)
|
||||
|
@ -84,8 +93,7 @@ func TestMaintCommandRun_EnableNodeMaintenance(t *testing.T) {
|
|||
a1 := testAgent(t)
|
||||
defer a1.Shutdown()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &MaintCommand{Ui: ui}
|
||||
ui, c := testMaintCommand(t)
|
||||
|
||||
args := []string{
|
||||
"-http-addr=" + a1.httpAddr,
|
||||
|
@ -106,8 +114,7 @@ func TestMaintCommandRun_DisableNodeMaintenance(t *testing.T) {
|
|||
a1 := testAgent(t)
|
||||
defer a1.Shutdown()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &MaintCommand{Ui: ui}
|
||||
ui, c := testMaintCommand(t)
|
||||
|
||||
args := []string{
|
||||
"-http-addr=" + a1.httpAddr,
|
||||
|
@ -136,8 +143,7 @@ func TestMaintCommandRun_EnableServiceMaintenance(t *testing.T) {
|
|||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &MaintCommand{Ui: ui}
|
||||
ui, c := testMaintCommand(t)
|
||||
|
||||
args := []string{
|
||||
"-http-addr=" + a1.httpAddr,
|
||||
|
@ -168,8 +174,7 @@ func TestMaintCommandRun_DisableServiceMaintenance(t *testing.T) {
|
|||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &MaintCommand{Ui: ui}
|
||||
ui, c := testMaintCommand(t)
|
||||
|
||||
args := []string{
|
||||
"-http-addr=" + a1.httpAddr,
|
||||
|
@ -190,8 +195,7 @@ func TestMaintCommandRun_ServiceMaintenance_NoService(t *testing.T) {
|
|||
a1 := testAgent(t)
|
||||
defer a1.Shutdown()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &MaintCommand{Ui: ui}
|
||||
ui, c := testMaintCommand(t)
|
||||
|
||||
args := []string{
|
||||
"-http-addr=" + a1.httpAddr,
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/hashicorp/consul/command/agent"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/ryanuber/columnize"
|
||||
"net"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
consulapi "github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/hashicorp/serf/serf"
|
||||
"github.com/ryanuber/columnize"
|
||||
)
|
||||
|
||||
// MembersCommand is a Command implementation that queries a running
|
||||
// Consul agent what members are part of the cluster currently.
|
||||
type MembersCommand struct {
|
||||
Ui cli.Ui
|
||||
base.Command
|
||||
}
|
||||
|
||||
func (c *MembersCommand) Help() string {
|
||||
|
@ -24,18 +25,8 @@ Usage: consul members [options]
|
|||
|
||||
Outputs the members of a running Consul agent.
|
||||
|
||||
Options:
|
||||
` + c.Command.Help()
|
||||
|
||||
-detailed Provides detailed information about nodes
|
||||
|
||||
-rpc-addr=127.0.0.1:8400 RPC address of the Consul agent.
|
||||
|
||||
-status=<regexp> If provided, output is filtered to only nodes matching
|
||||
the regular expression for status
|
||||
|
||||
-wan If the agent is in server mode, this can be used to return
|
||||
the other peers in the WAN pool
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
|
@ -43,13 +34,18 @@ func (c *MembersCommand) Run(args []string) int {
|
|||
var detailed bool
|
||||
var wan bool
|
||||
var statusFilter string
|
||||
cmdFlags := flag.NewFlagSet("members", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
cmdFlags.BoolVar(&detailed, "detailed", false, "detailed output")
|
||||
cmdFlags.BoolVar(&wan, "wan", false, "wan members")
|
||||
cmdFlags.StringVar(&statusFilter, "status", ".*", "status filter")
|
||||
rpcAddr := RPCAddrFlag(cmdFlags)
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
|
||||
f := c.Command.NewFlagSet(c)
|
||||
f.BoolVar(&detailed, "detailed", false,
|
||||
"Provides detailed information about nodes.")
|
||||
f.BoolVar(&wan, "wan", false,
|
||||
"If the agent is in server mode, this can be used to return the other "+
|
||||
"peers in the WAN pool.")
|
||||
f.StringVar(&statusFilter, "status", ".*",
|
||||
"If provided, output is filtered to only nodes matching the regular "+
|
||||
"expression for status.")
|
||||
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
|
@ -60,19 +56,13 @@ func (c *MembersCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
client, err := RPCClient(*rpcAddr)
|
||||
client, err := c.Command.HTTPClient()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
|
||||
return 1
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
var members []agent.Member
|
||||
if wan {
|
||||
members, err = client.WANMembers()
|
||||
} else {
|
||||
members, err = client.LANMembers()
|
||||
}
|
||||
members, err := client.Agent().Members(wan)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error retrieving members: %s", err))
|
||||
return 1
|
||||
|
@ -82,7 +72,8 @@ func (c *MembersCommand) Run(args []string) int {
|
|||
n := len(members)
|
||||
for i := 0; i < n; i++ {
|
||||
member := members[i]
|
||||
if !statusRe.MatchString(member.Status) {
|
||||
statusString := serf.MemberStatus(member.Status).String()
|
||||
if !statusRe.MatchString(statusString) {
|
||||
members[i], members[n-1] = members[n-1], members[i]
|
||||
i--
|
||||
n--
|
||||
|
@ -114,7 +105,7 @@ func (c *MembersCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// so we can sort members by name
|
||||
type ByMemberName []agent.Member
|
||||
type ByMemberName []*consulapi.AgentMember
|
||||
|
||||
func (m ByMemberName) Len() int { return len(m) }
|
||||
func (m ByMemberName) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
|
||||
|
@ -122,12 +113,12 @@ func (m ByMemberName) Less(i, j int) bool { return m[i].Name < m[j].Name }
|
|||
|
||||
// standardOutput is used to dump the most useful information about nodes
|
||||
// in a more human-friendly format
|
||||
func (c *MembersCommand) standardOutput(members []agent.Member) []string {
|
||||
func (c *MembersCommand) standardOutput(members []*consulapi.AgentMember) []string {
|
||||
result := make([]string, 0, len(members))
|
||||
header := "Node|Address|Status|Type|Build|Protocol|DC"
|
||||
result = append(result, header)
|
||||
for _, member := range members {
|
||||
addr := net.TCPAddr{IP: member.Addr, Port: int(member.Port)}
|
||||
addr := net.TCPAddr{IP: net.ParseIP(member.Addr), Port: int(member.Port)}
|
||||
protocol := member.Tags["vsn"]
|
||||
build := member.Tags["build"]
|
||||
if build == "" {
|
||||
|
@ -137,18 +128,19 @@ func (c *MembersCommand) standardOutput(members []agent.Member) []string {
|
|||
}
|
||||
dc := member.Tags["dc"]
|
||||
|
||||
statusString := serf.MemberStatus(member.Status).String()
|
||||
switch member.Tags["role"] {
|
||||
case "node":
|
||||
line := fmt.Sprintf("%s|%s|%s|client|%s|%s|%s",
|
||||
member.Name, addr.String(), member.Status, build, protocol, dc)
|
||||
member.Name, addr.String(), statusString, build, protocol, dc)
|
||||
result = append(result, line)
|
||||
case "consul":
|
||||
line := fmt.Sprintf("%s|%s|%s|server|%s|%s|%s",
|
||||
member.Name, addr.String(), member.Status, build, protocol, dc)
|
||||
member.Name, addr.String(), statusString, build, protocol, dc)
|
||||
result = append(result, line)
|
||||
default:
|
||||
line := fmt.Sprintf("%s|%s|%s|unknown|||",
|
||||
member.Name, addr.String(), member.Status)
|
||||
member.Name, addr.String(), statusString)
|
||||
result = append(result, line)
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +149,7 @@ func (c *MembersCommand) standardOutput(members []agent.Member) []string {
|
|||
|
||||
// detailedOutput is used to dump all known information about nodes in
|
||||
// their raw format
|
||||
func (c *MembersCommand) detailedOutput(members []agent.Member) []string {
|
||||
func (c *MembersCommand) detailedOutput(members []*consulapi.AgentMember) []string {
|
||||
result := make([]string, 0, len(members))
|
||||
header := "Node|Address|Status|Tags"
|
||||
result = append(result, header)
|
||||
|
@ -177,9 +169,9 @@ func (c *MembersCommand) detailedOutput(members []agent.Member) []string {
|
|||
|
||||
tags := strings.Join(tagPairs, ",")
|
||||
|
||||
addr := net.TCPAddr{IP: member.Addr, Port: int(member.Port)}
|
||||
addr := net.TCPAddr{IP: net.ParseIP(member.Addr), Port: int(member.Port)}
|
||||
line := fmt.Sprintf("%s|%s|%s|%s",
|
||||
member.Name, addr.String(), member.Status, tags)
|
||||
member.Name, addr.String(), serf.MemberStatus(member.Status).String(), tags)
|
||||
result = append(result, line)
|
||||
}
|
||||
return result
|
||||
|
|
|
@ -2,11 +2,22 @@ package command
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/mitchellh/cli"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testMembersCommand(t *testing.T) (*cli.MockUi, *MembersCommand) {
|
||||
ui := new(cli.MockUi)
|
||||
return ui, &MembersCommand{
|
||||
Command: base.Command{
|
||||
Ui: ui,
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestMembersCommand_implements(t *testing.T) {
|
||||
var _ cli.Command = &MembersCommand{}
|
||||
}
|
||||
|
@ -15,9 +26,8 @@ func TestMembersCommandRun(t *testing.T) {
|
|||
a1 := testAgent(t)
|
||||
defer a1.Shutdown()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &MembersCommand{Ui: ui}
|
||||
args := []string{"-rpc-addr=" + a1.addr}
|
||||
ui, c := testMembersCommand(t)
|
||||
args := []string{"-http-addr=" + a1.httpAddr}
|
||||
|
||||
code := c.Run(args)
|
||||
if code != 0 {
|
||||
|
@ -44,9 +54,8 @@ func TestMembersCommandRun_WAN(t *testing.T) {
|
|||
a1 := testAgent(t)
|
||||
defer a1.Shutdown()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &MembersCommand{Ui: ui}
|
||||
args := []string{"-rpc-addr=" + a1.addr, "-wan"}
|
||||
ui, c := testMembersCommand(t)
|
||||
args := []string{"-http-addr=" + a1.httpAddr, "-wan"}
|
||||
|
||||
code := c.Run(args)
|
||||
if code != 0 {
|
||||
|
@ -62,10 +71,9 @@ func TestMembersCommandRun_statusFilter(t *testing.T) {
|
|||
a1 := testAgent(t)
|
||||
defer a1.Shutdown()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &MembersCommand{Ui: ui}
|
||||
ui, c := testMembersCommand(t)
|
||||
args := []string{
|
||||
"-rpc-addr=" + a1.addr,
|
||||
"-http-addr=" + a1.httpAddr,
|
||||
"-status=a.*e",
|
||||
}
|
||||
|
||||
|
@ -83,10 +91,9 @@ func TestMembersCommandRun_statusFilter_failed(t *testing.T) {
|
|||
a1 := testAgent(t)
|
||||
defer a1.Shutdown()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &MembersCommand{Ui: ui}
|
||||
ui, c := testMembersCommand(t)
|
||||
args := []string{
|
||||
"-rpc-addr=" + a1.addr,
|
||||
"-http-addr=" + a1.httpAddr,
|
||||
"-status=(fail|left)",
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/hashicorp/logutils"
|
||||
"github.com/mitchellh/cli"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
)
|
||||
|
||||
// MonitorCommand is a Command implementation that queries a running
|
||||
// Consul agent what members are part of the cluster currently.
|
||||
type MonitorCommand struct {
|
||||
base.Command
|
||||
|
||||
ShutdownCh <-chan struct{}
|
||||
Ui cli.Ui
|
||||
|
||||
lock sync.Mutex
|
||||
quitting bool
|
||||
|
@ -29,40 +29,34 @@ Usage: consul monitor [options]
|
|||
example your agent may only be logging at INFO level, but with the monitor
|
||||
you can see the DEBUG level logs.
|
||||
|
||||
Options:
|
||||
` + c.Command.Help()
|
||||
|
||||
-log-level=info Log level of the agent.
|
||||
-rpc-addr=127.0.0.1:8400 RPC address of the Consul agent.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *MonitorCommand) Run(args []string) int {
|
||||
var logLevel string
|
||||
cmdFlags := flag.NewFlagSet("monitor", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
cmdFlags.StringVar(&logLevel, "log-level", "INFO", "log level")
|
||||
rpcAddr := RPCAddrFlag(cmdFlags)
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
|
||||
f := c.Command.NewFlagSet(c)
|
||||
f.StringVar(&logLevel, "log-level", "INFO", "Log level of the agent.")
|
||||
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
client, err := RPCClient(*rpcAddr)
|
||||
client, err := c.Command.HTTPClient()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
|
||||
return 1
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
logCh := make(chan string, 1024)
|
||||
monHandle, err := client.Monitor(logutils.LogLevel(logLevel), logCh)
|
||||
eventDoneCh := make(chan struct{})
|
||||
logCh, err := client.Agent().Monitor(logLevel, eventDoneCh, nil)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error starting monitor: %s", err))
|
||||
return 1
|
||||
}
|
||||
defer client.Stop(monHandle)
|
||||
|
||||
eventDoneCh := make(chan struct{})
|
||||
go func() {
|
||||
defer close(eventDoneCh)
|
||||
OUTER:
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"flag"
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/ryanuber/columnize"
|
||||
)
|
||||
|
||||
// OperatorCommand is used to provide various low-level tools for Consul
|
||||
// operators.
|
||||
type OperatorCommand struct {
|
||||
Ui cli.Ui
|
||||
base.Command
|
||||
}
|
||||
|
||||
func (c *OperatorCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: consul operator <subcommand> [common options] [action] [options]
|
||||
Usage: consul operator <subcommand> [action] [options]
|
||||
|
||||
Provides cluster-level tools for Consul operators, such as interacting with
|
||||
the Raft subsystem. NOTE: Use this command with extreme caution, as improper
|
||||
|
@ -31,11 +31,6 @@ Usage: consul operator <subcommand> [common options] [action] [options]
|
|||
Run consul operator <subcommand> with no arguments for help on that
|
||||
subcommand.
|
||||
|
||||
Common Options:
|
||||
|
||||
-http-addr=127.0.0.1:8500 HTTP address of the Consul agent.
|
||||
-token="" ACL token to use. Defaults to that of agent.
|
||||
|
||||
Subcommands:
|
||||
|
||||
raft View and modify Consul's Raft configuration.
|
||||
|
@ -73,17 +68,15 @@ func (c *OperatorCommand) Synopsis() string {
|
|||
}
|
||||
|
||||
const raftHelp = `
|
||||
Raft Subcommand Actions:
|
||||
Operator Raft Subcommand:
|
||||
|
||||
raft -list-peers -stale=[true|false]
|
||||
The raft subcommand can be used in two modes:
|
||||
|
||||
consul operator raft -list-peers
|
||||
|
||||
Displays the current Raft peer configuration.
|
||||
|
||||
The -stale argument defaults to "false" which means the leader provides the
|
||||
result. If the cluster is in an outage state without a leader, you may need
|
||||
to set -stale to "true" to get the configuration from a non-leader server.
|
||||
|
||||
raft -remove-peer -address="IP:port"
|
||||
consul operator raft -remove-peer -address="IP:port"
|
||||
|
||||
Removes Consul server with given -address from the Raft configuration.
|
||||
|
||||
|
@ -93,33 +86,39 @@ Raft Subcommand Actions:
|
|||
affects the Raft quorum. If the server still shows in the output of the
|
||||
"consul members" command, it is preferable to clean up by simply running
|
||||
"consul force-leave" instead of this command.
|
||||
|
||||
`
|
||||
|
||||
// raft handles the raft subcommands.
|
||||
func (c *OperatorCommand) raft(args []string) error {
|
||||
cmdFlags := flag.NewFlagSet("raft", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
f := c.Command.NewFlagSet(c)
|
||||
|
||||
// Parse verb arguments.
|
||||
var listPeers, removePeer bool
|
||||
cmdFlags.BoolVar(&listPeers, "list-peers", false, "")
|
||||
cmdFlags.BoolVar(&removePeer, "remove-peer", false, "")
|
||||
f.BoolVar(&listPeers, "list-peers", false,
|
||||
"If this flag is provided, the current Raft peer configuration will be "+
|
||||
"displayed. If the cluster is in an outage state without a leader, you may need "+
|
||||
"to set -stale to 'true' to get the configuration from a non-leader server.")
|
||||
f.BoolVar(&removePeer, "remove-peer", false,
|
||||
"If this flag is provided, the Consul server with the given -address will be "+
|
||||
"removed from the Raft configuration.")
|
||||
|
||||
// Parse other arguments.
|
||||
var stale bool
|
||||
var address, token string
|
||||
cmdFlags.StringVar(&address, "address", "", "")
|
||||
cmdFlags.BoolVar(&stale, "stale", false, "")
|
||||
cmdFlags.StringVar(&token, "token", "", "")
|
||||
httpAddr := HTTPAddrFlag(cmdFlags)
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
var address string
|
||||
f.StringVar(&address, "address", "",
|
||||
"The address to remove from the Raft configuration.")
|
||||
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
if err == flag.ErrHelp {
|
||||
c.Ui.Output("")
|
||||
c.Ui.Output(strings.TrimSpace(raftHelp + c.Command.Help()))
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Set up a client.
|
||||
conf := api.DefaultConfig()
|
||||
conf.Address = *httpAddr
|
||||
client, err := api.NewClient(conf)
|
||||
client, err := c.Command.HTTPClient()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error connecting to Consul agent: %s", err)
|
||||
}
|
||||
|
@ -129,8 +128,7 @@ func (c *OperatorCommand) raft(args []string) error {
|
|||
if listPeers {
|
||||
// Fetch the current configuration.
|
||||
q := &api.QueryOptions{
|
||||
AllowStale: stale,
|
||||
Token: token,
|
||||
AllowStale: c.Command.HTTPStale(),
|
||||
}
|
||||
reply, err := operator.RaftGetConfiguration(q)
|
||||
if err != nil {
|
||||
|
@ -156,17 +154,14 @@ func (c *OperatorCommand) raft(args []string) error {
|
|||
}
|
||||
|
||||
// Try to kick the peer.
|
||||
w := &api.WriteOptions{
|
||||
Token: token,
|
||||
}
|
||||
if err := operator.RaftRemovePeerByAddress(address, w); err != nil {
|
||||
if err := operator.RaftRemovePeerByAddress(address, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
c.Ui.Output(fmt.Sprintf("Removed peer with address %q", address))
|
||||
} else {
|
||||
c.Ui.Output(c.Help())
|
||||
c.Ui.Output("")
|
||||
c.Ui.Output(strings.TrimSpace(raftHelp))
|
||||
c.Ui.Output(strings.TrimSpace(raftHelp + c.Command.Help()))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -4,9 +4,20 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testOperatorCommand(t *testing.T) (*cli.MockUi, *OperatorCommand) {
|
||||
ui := new(cli.MockUi)
|
||||
return ui, &OperatorCommand{
|
||||
Command: base.Command{
|
||||
Ui: ui,
|
||||
Flags: base.FlagSetHTTP,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperator_Implements(t *testing.T) {
|
||||
var _ cli.Command = &OperatorCommand{}
|
||||
}
|
||||
|
@ -16,8 +27,7 @@ func TestOperator_Raft_ListPeers(t *testing.T) {
|
|||
defer a1.Shutdown()
|
||||
waitForLeader(t, a1.httpAddr)
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &OperatorCommand{Ui: ui}
|
||||
ui, c := testOperatorCommand(t)
|
||||
args := []string{"raft", "-http-addr=" + a1.httpAddr, "-list-peers"}
|
||||
|
||||
code := c.Run(args)
|
||||
|
@ -35,8 +45,7 @@ func TestOperator_Raft_RemovePeer(t *testing.T) {
|
|||
defer a1.Shutdown()
|
||||
waitForLeader(t, a1.httpAddr)
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &OperatorCommand{Ui: ui}
|
||||
ui, c := testOperatorCommand(t)
|
||||
args := []string{"raft", "-http-addr=" + a1.httpAddr, "-remove-peer", "-address=nope"}
|
||||
|
||||
code := c.Run(args)
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ReloadCommand is a Command implementation that instructs
|
||||
// the Consul agent to reload configurations
|
||||
type ReloadCommand struct {
|
||||
Ui cli.Ui
|
||||
base.Command
|
||||
}
|
||||
|
||||
func (c *ReloadCommand) Help() string {
|
||||
|
@ -20,29 +19,25 @@ Usage: consul reload
|
|||
Causes the agent to reload configurations. This can be used instead
|
||||
of sending the SIGHUP signal to the agent.
|
||||
|
||||
Options:
|
||||
` + c.Command.Help()
|
||||
|
||||
-rpc-addr=127.0.0.1:8400 RPC address of the Consul agent.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *ReloadCommand) Run(args []string) int {
|
||||
cmdFlags := flag.NewFlagSet("reload", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
rpcAddr := RPCAddrFlag(cmdFlags)
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
c.Command.NewFlagSet(c)
|
||||
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
client, err := RPCClient(*rpcAddr)
|
||||
client, err := c.Command.HTTPClient()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
|
||||
return 1
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
if err := client.Reload(); err != nil {
|
||||
if err := client.Agent().Reload(); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error reloading: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/cli"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func TestReloadCommand_implements(t *testing.T) {
|
||||
|
@ -11,12 +13,24 @@ func TestReloadCommand_implements(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestReloadCommandRun(t *testing.T) {
|
||||
a1 := testAgent(t)
|
||||
reloadCh := make(chan chan error)
|
||||
a1 := testAgentWithConfigReload(t, nil, reloadCh)
|
||||
defer a1.Shutdown()
|
||||
|
||||
// Setup a dummy response to errCh to simulate a successful reload
|
||||
go func() {
|
||||
errCh := <-reloadCh
|
||||
errCh <- nil
|
||||
}()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &ReloadCommand{Ui: ui}
|
||||
args := []string{"-rpc-addr=" + a1.addr}
|
||||
c := &ReloadCommand{
|
||||
Command: base.Command{
|
||||
Ui: ui,
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
},
|
||||
}
|
||||
args := []string{"-http-addr=" + a1.httpAddr}
|
||||
|
||||
code := c.Run(args)
|
||||
if code != 0 {
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/hashicorp/serf/coordinate"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
// RTTCommand is a Command implementation that allows users to query the
|
||||
// estimated round trip time between nodes using network coordinates.
|
||||
type RTTCommand struct {
|
||||
Ui cli.Ui
|
||||
base.Command
|
||||
}
|
||||
|
||||
func (c *RTTCommand) Help() string {
|
||||
|
@ -36,28 +34,24 @@ Usage: consul rtt [options] node1 [node2]
|
|||
because they are maintained by independent Serf gossip pools, so they are
|
||||
not compatible.
|
||||
|
||||
Options:
|
||||
` + c.Command.Help()
|
||||
|
||||
-wan Use WAN coordinates instead of LAN coordinates.
|
||||
-http-addr=127.0.0.1:8500 HTTP address of the Consul agent.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *RTTCommand) Run(args []string) int {
|
||||
var wan bool
|
||||
|
||||
cmdFlags := flag.NewFlagSet("rtt", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
f := c.Command.NewFlagSet(c)
|
||||
|
||||
cmdFlags.BoolVar(&wan, "wan", false, "wan")
|
||||
httpAddr := HTTPAddrFlag(cmdFlags)
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
f.BoolVar(&wan, "wan", false, "Use WAN coordinates instead of LAN coordinates.")
|
||||
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
// They must provide at least one node.
|
||||
nodes := cmdFlags.Args()
|
||||
nodes := f.Args()
|
||||
if len(nodes) < 1 || len(nodes) > 2 {
|
||||
c.Ui.Error("One or two node names must be specified")
|
||||
c.Ui.Error("")
|
||||
|
@ -66,9 +60,7 @@ func (c *RTTCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Create and test the HTTP client.
|
||||
conf := api.DefaultConfig()
|
||||
conf.Address = *httpAddr
|
||||
client, err := api.NewClient(conf)
|
||||
client, err := c.Command.HTTPClient()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
|
||||
return 1
|
||||
|
|
|
@ -7,19 +7,29 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/command/agent"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/hashicorp/consul/consul/structs"
|
||||
"github.com/hashicorp/consul/testutil"
|
||||
"github.com/hashicorp/serf/coordinate"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testRTTCommand(t *testing.T) (*cli.MockUi, *RTTCommand) {
|
||||
ui := new(cli.MockUi)
|
||||
return ui, &RTTCommand{
|
||||
Command: base.Command{
|
||||
Ui: ui,
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestRTTCommand_Implements(t *testing.T) {
|
||||
var _ cli.Command = &RTTCommand{}
|
||||
}
|
||||
|
||||
func TestRTTCommand_Run_BadArgs(t *testing.T) {
|
||||
ui := new(cli.MockUi)
|
||||
c := &RTTCommand{Ui: ui}
|
||||
_, c := testRTTCommand(t)
|
||||
|
||||
if code := c.Run([]string{}); code != 1 {
|
||||
t.Fatalf("expected return code 1, got %d", code)
|
||||
|
@ -90,8 +100,7 @@ func TestRTTCommand_Run_LAN(t *testing.T) {
|
|||
}
|
||||
|
||||
// Ask for the RTT of two known nodes
|
||||
ui := new(cli.MockUi)
|
||||
c := &RTTCommand{Ui: ui}
|
||||
ui, c := testRTTCommand(t)
|
||||
args := []string{
|
||||
"-http-addr=" + a.httpAddr,
|
||||
a.config.NodeName,
|
||||
|
@ -118,8 +127,7 @@ func TestRTTCommand_Run_LAN(t *testing.T) {
|
|||
|
||||
// Default to the agent's node.
|
||||
{
|
||||
ui := new(cli.MockUi)
|
||||
c := &RTTCommand{Ui: ui}
|
||||
ui, c := testRTTCommand(t)
|
||||
args := []string{
|
||||
"-http-addr=" + a.httpAddr,
|
||||
"dogs",
|
||||
|
@ -138,8 +146,7 @@ func TestRTTCommand_Run_LAN(t *testing.T) {
|
|||
|
||||
// Try an unknown node.
|
||||
{
|
||||
ui := new(cli.MockUi)
|
||||
c := &RTTCommand{Ui: ui}
|
||||
ui, c := testRTTCommand(t)
|
||||
args := []string{
|
||||
"-http-addr=" + a.httpAddr,
|
||||
a.config.NodeName,
|
||||
|
@ -162,8 +169,7 @@ func TestRTTCommand_Run_WAN(t *testing.T) {
|
|||
// We can't easily inject WAN coordinates, so we will just query the
|
||||
// node with itself.
|
||||
{
|
||||
ui := new(cli.MockUi)
|
||||
c := &RTTCommand{Ui: ui}
|
||||
ui, c := testRTTCommand(t)
|
||||
args := []string{
|
||||
"-wan",
|
||||
"-http-addr=" + a.httpAddr,
|
||||
|
@ -183,8 +189,7 @@ func TestRTTCommand_Run_WAN(t *testing.T) {
|
|||
|
||||
// Default to the agent's node.
|
||||
{
|
||||
ui := new(cli.MockUi)
|
||||
c := &RTTCommand{Ui: ui}
|
||||
ui, c := testRTTCommand(t)
|
||||
args := []string{
|
||||
"-wan",
|
||||
"-http-addr=" + a.httpAddr,
|
||||
|
@ -203,8 +208,7 @@ func TestRTTCommand_Run_WAN(t *testing.T) {
|
|||
|
||||
// Try an unknown node.
|
||||
{
|
||||
ui := new(cli.MockUi)
|
||||
c := &RTTCommand{Ui: ui}
|
||||
ui, c := testRTTCommand(t)
|
||||
args := []string{
|
||||
"-wan",
|
||||
"-http-addr=" + a.httpAddr,
|
||||
|
|
|
@ -2,20 +2,19 @@ package command
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/hashicorp/consul/snapshot"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
// SnapshotInspectCommand is a Command implementation that is used to display
|
||||
// metadata about a snapshot file
|
||||
type SnapshotInspectCommand struct {
|
||||
Ui cli.Ui
|
||||
base.Command
|
||||
}
|
||||
|
||||
func (c *SnapshotInspectCommand) Help() string {
|
||||
|
@ -35,15 +34,15 @@ Usage: consul snapshot inspect [options] FILE
|
|||
}
|
||||
|
||||
func (c *SnapshotInspectCommand) Run(args []string) int {
|
||||
cmdFlags := flag.NewFlagSet("get", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
flagSet := c.Command.NewFlagSet(c)
|
||||
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
var file string
|
||||
|
||||
args = cmdFlags.Args()
|
||||
args = flagSet.Args()
|
||||
switch len(args) {
|
||||
case 0:
|
||||
c.Ui.Error("Missing FILE argument")
|
||||
|
|
|
@ -8,9 +8,20 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testSnapshotInspectCommand(t *testing.T) (*cli.MockUi, *SnapshotInspectCommand) {
|
||||
ui := new(cli.MockUi)
|
||||
return ui, &SnapshotInspectCommand{
|
||||
Command: base.Command{
|
||||
Ui: ui,
|
||||
Flags: base.FlagSetNone,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshotInspectCommand_implements(t *testing.T) {
|
||||
var _ cli.Command = &SnapshotInspectCommand{}
|
||||
}
|
||||
|
@ -20,8 +31,7 @@ func TestSnapshotInspectCommand_noTabs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSnapshotInspectCommand_Validation(t *testing.T) {
|
||||
ui := new(cli.MockUi)
|
||||
c := &SnapshotInspectCommand{Ui: ui}
|
||||
ui, c := testSnapshotInspectCommand(t)
|
||||
|
||||
cases := map[string]struct {
|
||||
args []string
|
||||
|
@ -63,8 +73,6 @@ func TestSnapshotInspectCommand_Run(t *testing.T) {
|
|||
defer srv.Shutdown()
|
||||
waitForLeader(t, srv.httpAddr)
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
|
||||
dir, err := ioutil.TempDir("", "snapshot")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
|
@ -93,10 +101,10 @@ func TestSnapshotInspectCommand_Run(t *testing.T) {
|
|||
}
|
||||
|
||||
// Inspect the snapshot
|
||||
inspect := &SnapshotInspectCommand{Ui: ui}
|
||||
ui, c := testSnapshotInspectCommand(t)
|
||||
args := []string{file}
|
||||
|
||||
code := inspect.Run(args)
|
||||
code := c.Run(args)
|
||||
if code != 0 {
|
||||
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
)
|
||||
|
||||
// SnapshotRestoreCommand is a Command implementation that is used to restore
|
||||
// the state of the Consul servers for disaster recovery.
|
||||
type SnapshotRestoreCommand struct {
|
||||
Ui cli.Ui
|
||||
base.Command
|
||||
}
|
||||
|
||||
func (c *SnapshotRestoreCommand) Help() string {
|
||||
|
@ -38,24 +36,21 @@ Usage: consul snapshot restore [options] FILE
|
|||
|
||||
For a full list of options and examples, please see the Consul documentation.
|
||||
|
||||
` + apiOptsText
|
||||
` + c.Command.Help()
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *SnapshotRestoreCommand) Run(args []string) int {
|
||||
cmdFlags := flag.NewFlagSet("get", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
datacenter := cmdFlags.String("datacenter", "", "")
|
||||
token := cmdFlags.String("token", "", "")
|
||||
httpAddr := HTTPAddrFlag(cmdFlags)
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
flagSet := c.Command.NewFlagSet(c)
|
||||
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
var file string
|
||||
|
||||
args = cmdFlags.Args()
|
||||
args = flagSet.Args()
|
||||
switch len(args) {
|
||||
case 0:
|
||||
c.Ui.Error("Missing FILE argument")
|
||||
|
@ -68,11 +63,7 @@ func (c *SnapshotRestoreCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Create and test the HTTP client
|
||||
conf := api.DefaultConfig()
|
||||
conf.Datacenter = *datacenter
|
||||
conf.Address = *httpAddr
|
||||
conf.Token = *token
|
||||
client, err := api.NewClient(conf)
|
||||
client, err := c.Command.HTTPClient()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
|
||||
return 1
|
||||
|
|
|
@ -8,9 +8,20 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testSnapshotRestoreCommand(t *testing.T) (*cli.MockUi, *SnapshotRestoreCommand) {
|
||||
ui := new(cli.MockUi)
|
||||
return ui, &SnapshotRestoreCommand{
|
||||
Command: base.Command{
|
||||
Ui: ui,
|
||||
Flags: base.FlagSetHTTP,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshotRestoreCommand_implements(t *testing.T) {
|
||||
var _ cli.Command = &SnapshotRestoreCommand{}
|
||||
}
|
||||
|
@ -20,8 +31,7 @@ func TestSnapshotRestoreCommand_noTabs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSnapshotRestoreCommand_Validation(t *testing.T) {
|
||||
ui := new(cli.MockUi)
|
||||
c := &SnapshotRestoreCommand{Ui: ui}
|
||||
ui, c := testSnapshotRestoreCommand(t)
|
||||
|
||||
cases := map[string]struct {
|
||||
args []string
|
||||
|
@ -63,8 +73,7 @@ func TestSnapshotRestoreCommand_Run(t *testing.T) {
|
|||
defer srv.Shutdown()
|
||||
waitForLeader(t, srv.httpAddr)
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &SnapshotSaveCommand{Ui: ui}
|
||||
ui, c := testSnapshotRestoreCommand(t)
|
||||
|
||||
dir, err := ioutil.TempDir("", "snapshot")
|
||||
if err != nil {
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/hashicorp/consul/snapshot"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
// SnapshotSaveCommand is a Command implementation that is used to save the
|
||||
// state of the Consul servers for disaster recovery.
|
||||
type SnapshotSaveCommand struct {
|
||||
Ui cli.Ui
|
||||
base.Command
|
||||
}
|
||||
|
||||
func (c *SnapshotSaveCommand) Help() string {
|
||||
|
@ -40,25 +39,21 @@ Usage: consul snapshot save [options] FILE
|
|||
|
||||
For a full list of options and examples, please see the Consul documentation.
|
||||
|
||||
` + apiOptsText
|
||||
` + c.Command.Help()
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *SnapshotSaveCommand) Run(args []string) int {
|
||||
cmdFlags := flag.NewFlagSet("get", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
datacenter := cmdFlags.String("datacenter", "", "")
|
||||
token := cmdFlags.String("token", "", "")
|
||||
stale := cmdFlags.Bool("stale", false, "")
|
||||
httpAddr := HTTPAddrFlag(cmdFlags)
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
flagSet := c.Command.NewFlagSet(c)
|
||||
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
var file string
|
||||
|
||||
args = cmdFlags.Args()
|
||||
args = flagSet.Args()
|
||||
switch len(args) {
|
||||
case 0:
|
||||
c.Ui.Error("Missing FILE argument")
|
||||
|
@ -71,11 +66,7 @@ func (c *SnapshotSaveCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Create and test the HTTP client
|
||||
conf := api.DefaultConfig()
|
||||
conf.Datacenter = *datacenter
|
||||
conf.Address = *httpAddr
|
||||
conf.Token = *token
|
||||
client, err := api.NewClient(conf)
|
||||
client, err := c.Command.HTTPClient()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
|
||||
return 1
|
||||
|
@ -83,7 +74,7 @@ func (c *SnapshotSaveCommand) Run(args []string) int {
|
|||
|
||||
// Take the snapshot.
|
||||
snap, qm, err := client.Snapshot().Save(&api.QueryOptions{
|
||||
AllowStale: *stale,
|
||||
AllowStale: c.Command.HTTPStale(),
|
||||
})
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error saving snapshot: %s", err))
|
||||
|
|
|
@ -7,9 +7,20 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testSnapshotSaveCommand(t *testing.T) (*cli.MockUi, *SnapshotSaveCommand) {
|
||||
ui := new(cli.MockUi)
|
||||
return ui, &SnapshotSaveCommand{
|
||||
Command: base.Command{
|
||||
Ui: ui,
|
||||
Flags: base.FlagSetHTTP,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshotSaveCommand_implements(t *testing.T) {
|
||||
var _ cli.Command = &SnapshotSaveCommand{}
|
||||
}
|
||||
|
@ -19,8 +30,7 @@ func TestSnapshotSaveCommand_noTabs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSnapshotSaveCommand_Validation(t *testing.T) {
|
||||
ui := new(cli.MockUi)
|
||||
c := &SnapshotSaveCommand{Ui: ui}
|
||||
ui, c := testSnapshotSaveCommand(t)
|
||||
|
||||
cases := map[string]struct {
|
||||
args []string
|
||||
|
@ -62,8 +72,7 @@ func TestSnapshotSaveCommand_Run(t *testing.T) {
|
|||
defer srv.Shutdown()
|
||||
waitForLeader(t, srv.httpAddr)
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &SnapshotSaveCommand{Ui: ui}
|
||||
ui, c := testSnapshotSaveCommand(t)
|
||||
|
||||
dir, err := ioutil.TempDir("", "snapshot")
|
||||
if err != nil {
|
||||
|
|
|
@ -44,7 +44,7 @@ func (a *agentWrapper) Shutdown() {
|
|||
}
|
||||
|
||||
func testAgent(t *testing.T) *agentWrapper {
|
||||
return testAgentWithConfig(t, func(c *agent.Config) {})
|
||||
return testAgentWithConfig(t, nil)
|
||||
}
|
||||
|
||||
func testAgentWithAPIClient(t *testing.T) (*agentWrapper, *api.Client) {
|
||||
|
@ -57,6 +57,10 @@ func testAgentWithAPIClient(t *testing.T) (*agentWrapper, *api.Client) {
|
|||
}
|
||||
|
||||
func testAgentWithConfig(t *testing.T, cb func(c *agent.Config)) *agentWrapper {
|
||||
return testAgentWithConfigReload(t, cb, nil)
|
||||
}
|
||||
|
||||
func testAgentWithConfigReload(t *testing.T, cb func(c *agent.Config), reloadCh chan chan error) *agentWrapper {
|
||||
l, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
|
@ -66,7 +70,9 @@ func testAgentWithConfig(t *testing.T, cb func(c *agent.Config)) *agentWrapper {
|
|||
mult := io.MultiWriter(os.Stderr, lw)
|
||||
|
||||
conf := nextConfig()
|
||||
cb(conf)
|
||||
if cb != nil {
|
||||
cb(conf)
|
||||
}
|
||||
|
||||
dir, err := ioutil.TempDir("", "agent")
|
||||
if err != nil {
|
||||
|
@ -74,7 +80,7 @@ func testAgentWithConfig(t *testing.T, cb func(c *agent.Config)) *agentWrapper {
|
|||
}
|
||||
conf.DataDir = dir
|
||||
|
||||
a, err := agent.Create(conf, lw, nil, nil)
|
||||
a, err := agent.Create(conf, lw, nil, reloadCh)
|
||||
if err != nil {
|
||||
os.RemoveAll(dir)
|
||||
t.Fatalf(fmt.Sprintf("err: %v", err))
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/cli"
|
||||
"testing"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func TestVersionCommand_implements(t *testing.T) {
|
||||
|
|
|
@ -3,22 +3,21 @@ package command
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/consul/command/agent"
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/hashicorp/consul/watch"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
// WatchCommand is a Command implementation that is used to setup
|
||||
// a "watch" which uses a sub-process
|
||||
type WatchCommand struct {
|
||||
base.Command
|
||||
ShutdownCh <-chan struct{}
|
||||
Ui cli.Ui
|
||||
}
|
||||
|
||||
func (c *WatchCommand) Help() string {
|
||||
|
@ -32,49 +31,36 @@ Usage: consul watch [options] [child...]
|
|||
Providing the watch type is required, and other parameters may be required
|
||||
or supported depending on the watch type.
|
||||
|
||||
Options:
|
||||
` + c.Command.Help()
|
||||
|
||||
-http-addr=127.0.0.1:8500 HTTP address of the Consul agent.
|
||||
-datacenter="" Datacenter to query. Defaults to that of agent.
|
||||
-token="" ACL token to use. Defaults to that of agent.
|
||||
-stale=[true|false] Specifies if watch data is permitted to be stale.
|
||||
Defaults to false.
|
||||
|
||||
Watch Specification:
|
||||
|
||||
-key=val Specifies the key to watch. Only for 'key' type.
|
||||
-name=val Specifies an event name to watch. Only for 'event' type.
|
||||
-passingonly=[true|false] Specifies if only hosts passing all checks are displayed.
|
||||
Optional for 'service' type. Defaults false.
|
||||
-prefix=val Specifies the key prefix to watch. Only for 'keyprefix' type.
|
||||
-service=val Specifies the service to watch. Required for 'service' type,
|
||||
optional for 'checks' type.
|
||||
-state=val Specifies the states to watch. Optional for 'checks' type.
|
||||
-tag=val Specifies the service tag to filter on. Optional for 'service'
|
||||
type.
|
||||
-type=val Specifies the watch type. One of key, keyprefix
|
||||
services, nodes, service, checks, or event.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *WatchCommand) Run(args []string) int {
|
||||
var watchType, datacenter, token, key, prefix, service, tag, passingOnly, stale, state, name string
|
||||
cmdFlags := flag.NewFlagSet("watch", flag.ContinueOnError)
|
||||
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
cmdFlags.StringVar(&watchType, "type", "", "")
|
||||
cmdFlags.StringVar(&datacenter, "datacenter", "", "")
|
||||
cmdFlags.StringVar(&token, "token", "", "")
|
||||
cmdFlags.StringVar(&key, "key", "", "")
|
||||
cmdFlags.StringVar(&prefix, "prefix", "", "")
|
||||
cmdFlags.StringVar(&service, "service", "", "")
|
||||
cmdFlags.StringVar(&tag, "tag", "", "")
|
||||
cmdFlags.StringVar(&passingOnly, "passingonly", "", "")
|
||||
cmdFlags.StringVar(&stale, "stale", "", "")
|
||||
cmdFlags.StringVar(&state, "state", "", "")
|
||||
cmdFlags.StringVar(&name, "name", "", "")
|
||||
httpAddr := HTTPAddrFlag(cmdFlags)
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
var watchType, key, prefix, service, tag, passingOnly, state, name string
|
||||
|
||||
f := c.Command.NewFlagSet(c)
|
||||
f.StringVar(&watchType, "type", "",
|
||||
"Specifies the watch type. One of key, keyprefix services, nodes, "+
|
||||
"service, checks, or event.")
|
||||
f.StringVar(&key, "key", "",
|
||||
"Specifies the key to watch. Only for 'key' type.")
|
||||
f.StringVar(&prefix, "prefix", "",
|
||||
"Specifies the key prefix to watch. Only for 'keyprefix' type.")
|
||||
f.StringVar(&service, "service", "",
|
||||
"Specifies the service to watch. Required for 'service' type, "+
|
||||
"optional for 'checks' type.")
|
||||
f.StringVar(&tag, "tag", "",
|
||||
"Specifies the service tag to filter on. Optional for 'service' type.")
|
||||
f.StringVar(&passingOnly, "passingonly", "",
|
||||
"Specifies if only hosts passing all checks are displayed. "+
|
||||
"Optional for 'service' type, must be one of `[true|false]`. Defaults false.")
|
||||
f.StringVar(&state, "state", "",
|
||||
"Specifies the states to watch. Optional for 'checks' type.")
|
||||
f.StringVar(&name, "name", "",
|
||||
"Specifies an event name to watch. Only for 'event' type.")
|
||||
|
||||
if err := c.Command.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
|
@ -87,18 +73,18 @@ func (c *WatchCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Grab the script to execute if any
|
||||
script := strings.Join(cmdFlags.Args(), " ")
|
||||
script := strings.Join(f.Args(), " ")
|
||||
|
||||
// Compile the watch parameters
|
||||
params := make(map[string]interface{})
|
||||
if watchType != "" {
|
||||
params["type"] = watchType
|
||||
}
|
||||
if datacenter != "" {
|
||||
params["datacenter"] = datacenter
|
||||
if c.Command.HTTPDatacenter() != "" {
|
||||
params["datacenter"] = c.Command.HTTPDatacenter()
|
||||
}
|
||||
if token != "" {
|
||||
params["token"] = token
|
||||
if c.Command.HTTPToken() != "" {
|
||||
params["token"] = c.Command.HTTPToken()
|
||||
}
|
||||
if key != "" {
|
||||
params["key"] = key
|
||||
|
@ -112,13 +98,8 @@ func (c *WatchCommand) Run(args []string) int {
|
|||
if tag != "" {
|
||||
params["tag"] = tag
|
||||
}
|
||||
if stale != "" {
|
||||
b, err := strconv.ParseBool(stale)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Failed to parse stale flag: %s", err))
|
||||
return 1
|
||||
}
|
||||
params["stale"] = b
|
||||
if c.Command.HTTPStale() {
|
||||
params["stale"] = c.Command.HTTPStale()
|
||||
}
|
||||
if state != "" {
|
||||
params["state"] = state
|
||||
|
@ -143,7 +124,7 @@ func (c *WatchCommand) Run(args []string) int {
|
|||
}
|
||||
|
||||
// Create and test the HTTP client
|
||||
client, err := HTTPClient(*httpAddr)
|
||||
client, err := c.Command.HTTPClient()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
|
||||
return 1
|
||||
|
@ -213,7 +194,7 @@ func (c *WatchCommand) Run(args []string) int {
|
|||
}()
|
||||
|
||||
// Run the watch
|
||||
if err := wp.Run(*httpAddr); err != nil {
|
||||
if err := wp.Run(c.Command.HTTPAddr()); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error querying Consul agent: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/cli"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/command/base"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func TestWatchCommand_implements(t *testing.T) {
|
||||
|
@ -15,7 +17,12 @@ func TestWatchCommandRun(t *testing.T) {
|
|||
defer a1.Shutdown()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &WatchCommand{Ui: ui}
|
||||
c := &WatchCommand{
|
||||
Command: base.Command{
|
||||
Ui: ui,
|
||||
Flags: base.FlagSetHTTP,
|
||||
},
|
||||
}
|
||||
args := []string{"-http-addr=" + a1.httpAddr, "-type=nodes"}
|
||||
|
||||
code := c.Run(args)
|
||||
|
|
55
commands.go
55
commands.go
|
@ -159,7 +159,10 @@ func init() {
|
|||
|
||||
"leave": func() (cli.Command, error) {
|
||||
return &command.LeaveCommand{
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
|
@ -175,38 +178,56 @@ func init() {
|
|||
|
||||
"maint": func() (cli.Command, error) {
|
||||
return &command.MaintCommand{
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
"members": func() (cli.Command, error) {
|
||||
return &command.MembersCommand{
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
"monitor": func() (cli.Command, error) {
|
||||
return &command.MonitorCommand{
|
||||
ShutdownCh: makeShutdownCh(),
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
"operator": func() (cli.Command, error) {
|
||||
return &command.OperatorCommand{
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetHTTP,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
"reload": func() (cli.Command, error) {
|
||||
return &command.ReloadCommand{
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
"rtt": func() (cli.Command, error) {
|
||||
return &command.RTTCommand{
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetClientHTTP,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
|
@ -218,19 +239,28 @@ func init() {
|
|||
|
||||
"snapshot restore": func() (cli.Command, error) {
|
||||
return &command.SnapshotRestoreCommand{
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetHTTP,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
"snapshot save": func() (cli.Command, error) {
|
||||
return &command.SnapshotSaveCommand{
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetHTTP,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
"snapshot inspect": func() (cli.Command, error) {
|
||||
return &command.SnapshotInspectCommand{
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetNone,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
|
@ -244,7 +274,10 @@ func init() {
|
|||
"watch": func() (cli.Command, error) {
|
||||
return &command.WatchCommand{
|
||||
ShutdownCh: makeShutdownCh(),
|
||||
Ui: ui,
|
||||
Command: base.Command{
|
||||
Flags: base.FlagSetHTTP,
|
||||
Ui: ui,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
|
|
@ -21,12 +21,8 @@ non-graceful leave can affect cluster availability.
|
|||
|
||||
## Usage
|
||||
|
||||
Usage: `consul leave`
|
||||
Usage: `consul leave [options]`
|
||||
|
||||
The command-line flags are all optional. The list of available flags are:
|
||||
|
||||
* `-rpc-addr` - Address to the RPC server of the agent you want to contact
|
||||
to send this command. If this isn't specified, the command checks the
|
||||
CONSUL_RPC_ADDR env variable. If this isn't set, the default RPC
|
||||
address will be set to "127.0.0.1:8400".
|
||||
#### API Options
|
||||
|
||||
<%= partial "docs/commands/http_api_options_client" %>
|
|
@ -24,9 +24,11 @@ health check.
|
|||
|
||||
Usage: `consul maint [options]`
|
||||
|
||||
All of the command line arguments are optional.
|
||||
#### API Options
|
||||
|
||||
The list of available flags are:
|
||||
<%= partial "docs/commands/http_api_options_client" %>
|
||||
|
||||
#### Command Options
|
||||
|
||||
* `-enable` - Enable maintenance mode on a given service or node. If
|
||||
combined with the `-service` flag, we operate on a specific service ID.
|
||||
|
@ -44,12 +46,6 @@ The list of available flags are:
|
|||
providing this flag, the `-enable` and `-disable` flags functionality is
|
||||
modified to operate on the given service ID.
|
||||
|
||||
* `-token` - ACL token to use. Defaults to that of agent.
|
||||
|
||||
* `-http-addr` - Address to the HTTP server of the agent you want to contact
|
||||
to send this command. If this isn't specified, the command will contact
|
||||
"127.0.0.1:8500" which is the default HTTP address of a Consul agent.
|
||||
|
||||
## List mode
|
||||
|
||||
If neither `-enable` nor `-disable` are passed, the `maint` command will
|
|
@ -22,16 +22,15 @@ that the failure is actually just a network partition.
|
|||
|
||||
Usage: `consul members [options]`
|
||||
|
||||
The command-line flags are all optional. The list of available flags are:
|
||||
#### API Options
|
||||
|
||||
<%= partial "docs/commands/http_api_options_client" %>
|
||||
|
||||
#### Command Options
|
||||
|
||||
* `-detailed` - If provided, output shows more detailed information
|
||||
about each node.
|
||||
|
||||
* `-rpc-addr` - Address to the RPC server of the agent you want to contact
|
||||
to send this command.If this isn't specified, the command checks the
|
||||
CONSUL_RPC_ADDR env variable. If this isn't set, the default RPC
|
||||
address will be set to "127.0.0.1:8400".
|
||||
|
||||
* `-status` - If provided, output is filtered to only nodes matching
|
||||
the regular expression for status
|
||||
|
|
@ -22,14 +22,13 @@ logs and watch the debug logs if necessary.
|
|||
|
||||
Usage: `consul monitor [options]`
|
||||
|
||||
The command-line flags are all optional. The list of available flags are:
|
||||
#### API Options
|
||||
|
||||
<%= partial "docs/commands/http_api_options_client" %>
|
||||
|
||||
#### Command Options
|
||||
|
||||
* `-log-level` - The log level of the messages to show. By default this
|
||||
is "info". This log level can be more verbose than what the agent is
|
||||
configured to run at. Available log levels are "trace", "debug", "info",
|
||||
"warn", and "err".
|
||||
|
||||
* `-rpc-addr` - Address to the RPC server of the agent you want to contact
|
||||
to send this command. If this isn't specified, the command checks the
|
||||
CONSUL_RPC_ADDR env variable. If this isn't set, the default RPC
|
||||
address will be set to "127.0.0.1:8400".
|
|
@ -28,20 +28,17 @@ endpoint.
|
|||
|
||||
## Usage
|
||||
|
||||
Usage: `consul operator <subcommand> [common options] [action] [options]`
|
||||
Usage: `consul operator <subcommand> [action] [options]`
|
||||
|
||||
Run `consul operator <subcommand>` with no arguments for help on that
|
||||
subcommand. The following subcommands are available:
|
||||
|
||||
* `raft` - View and modify Consul's Raft configuration.
|
||||
|
||||
Options common to all subcommands include:
|
||||
#### API Options
|
||||
|
||||
* `-http-addr` - Address to the HTTP server of the agent you want to contact
|
||||
to send this command. If this isn't specified, the command will contact
|
||||
"127.0.0.1:8500" which is the default HTTP address of a Consul agent.
|
||||
|
||||
* `-token` - ACL token to use. Defaults to that of agent.
|
||||
<%= partial "docs/commands/http_api_options_client" %>
|
||||
<%= partial "docs/commands/http_api_options_server" %>
|
||||
|
||||
## Raft Operations
|
||||
|
|
@ -29,10 +29,6 @@ section on the agent options page for details on which options are supported.
|
|||
|
||||
Usage: `consul reload`
|
||||
|
||||
The command-line flags are all optional. The list of available flags are:
|
||||
|
||||
* `-rpc-addr` - Address to the RPC server of the agent you want to contact
|
||||
to send this command. If this isn't specified, the command checks the
|
||||
CONSUL_RPC_ADDR env variable. If this isn't set, the default RPC
|
||||
address will be set to "127.0.0.1:8400".
|
||||
#### API Options
|
||||
|
||||
<%= partial "docs/commands/http_api_options_client" %>
|
|
@ -24,7 +24,11 @@ At least one node name is required. If the second node name isn't given, it
|
|||
is set to the agent's node name. These are the node names as known to
|
||||
Consul as the `consul members` command would show, not IP addresses.
|
||||
|
||||
The list of available flags are:
|
||||
#### API Options
|
||||
|
||||
<%= partial "docs/commands/http_api_options_client" %>
|
||||
|
||||
#### Command Options
|
||||
|
||||
* `-wan` - Instructs the command to use WAN coordinates instead of LAN
|
||||
coordinates. By default, the two nodes are assumed to be nodes in the local
|
||||
|
@ -33,11 +37,6 @@ The list of available flags are:
|
|||
and the datacenter (eg. "myserver.dc1"). It is not possible to measure between
|
||||
LAN coordinates and WAN coordinates, so both nodes must be in the same pool.
|
||||
|
||||
|
||||
* `-http-addr` - Address to the HTTP server of the agent you want to contact
|
||||
to send this command. If this isn't specified, the command will contact
|
||||
"127.0.0.1:8500" which is the default HTTP address of a Consul agent.
|
||||
|
||||
The following environment variables control accessing the HTTP server via SSL:
|
||||
|
||||
* `CONSUL_HTTP_SSL` Set this to enable SSL
|
|
@ -28,6 +28,7 @@ Usage: `consul snapshot restore [options] FILE`
|
|||
#### API Options
|
||||
|
||||
<%= partial "docs/commands/http_api_options_client" %>
|
||||
<%= partial "docs/commands/http_api_options_server" %>
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ Usage: `consul snapshot save [options] FILE`
|
|||
#### API Options
|
||||
|
||||
<%= partial "docs/commands/http_api_options_client" %>
|
||||
<%= partial "docs/commands/http_api_options_server" %>
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -41,7 +42,7 @@ After the snapshot is written to the given file it is read back and verified for
|
|||
integrity.
|
||||
|
||||
To create a potentially stale snapshot from any available server, use the stale
|
||||
consisentcy mode:
|
||||
consistency mode:
|
||||
|
||||
```text
|
||||
$ consul snapshot save -stale backup.snap
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
layout: "docs"
|
||||
page_title: "Commands: Version"
|
||||
sidebar_current: "docs-commands-version"
|
||||
description: |-
|
||||
The `version` command prints the version of Consul and the protocol versions it understands for speaking to other agents.
|
||||
|
||||
---
|
||||
|
||||
# Consul Version
|
||||
|
||||
Command: `consul version`
|
||||
|
||||
The `version` command prints the version of Consul and the protocol versions it understands for speaking to other agents.
|
||||
|
||||
```text
|
||||
$ consul version
|
||||
Consul v0.7.4
|
||||
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
|
||||
```
|
|
@ -27,18 +27,12 @@ data view. Depending on the type, various options may be required
|
|||
or optionally provided. There is more documentation on watch
|
||||
[specifications here](/docs/agent/watches.html).
|
||||
|
||||
The list of available flags are:
|
||||
#### API Options
|
||||
|
||||
* `-http-addr` - Address to the HTTP server of the agent you want to contact
|
||||
to send this command. If this isn't specified, the command will contact
|
||||
"127.0.0.1:8500" which is the default HTTP address of a Consul agent.
|
||||
<%= partial "docs/commands/http_api_options_client" %>
|
||||
<%= partial "docs/commands/http_api_options_server" %>
|
||||
|
||||
* `-datacenter` - Datacenter to query. Defaults to that of the agent.
|
||||
|
||||
* `-token` - ACL token to use. Defaults to that of the agent.
|
||||
|
||||
* `-stale=[true|false]` - Specifies if watch data is permitted to be stale. Defaults
|
||||
to false.
|
||||
#### Command Options
|
||||
|
||||
* `-key` - Key to watch. Only for `key` type.
|
||||
|
|
@ -173,6 +173,10 @@
|
|||
</ul>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-commands-version") %>>
|
||||
<a href="/docs/commands/version.html">version</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-commands-watch") %>>
|
||||
<a href="/docs/commands/watch.html">watch</a>
|
||||
</li>
|
||||
|
|
Loading…
Reference in New Issue