Convert watch command to use base.Command

This commit is contained in:
Kyle Havlovitz 2017-02-09 20:36:01 -05:00
parent edbb0ce0b8
commit ea66375063
No known key found for this signature in database
GPG Key ID: 8A5E6B173056AD6C
5 changed files with 65 additions and 68 deletions

View File

@ -58,6 +58,18 @@ func (c *Command) HTTPClient() (*api.Client, error) {
return api.NewClient(config) 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()
}
func (c *Command) HTTPStale() bool { func (c *Command) HTTPStale() bool {
var stale bool var stale bool
c.stale.Merge(&stale) c.stale.Merge(&stale)

View File

@ -3,22 +3,21 @@ package command
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"flag"
"fmt" "fmt"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"github.com/hashicorp/consul/command/agent" "github.com/hashicorp/consul/command/agent"
"github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/watch" "github.com/hashicorp/consul/watch"
"github.com/mitchellh/cli"
) )
// WatchCommand is a Command implementation that is used to setup // WatchCommand is a Command implementation that is used to setup
// a "watch" which uses a sub-process // a "watch" which uses a sub-process
type WatchCommand struct { type WatchCommand struct {
base.Command
ShutdownCh <-chan struct{} ShutdownCh <-chan struct{}
Ui cli.Ui
} }
func (c *WatchCommand) Help() string { 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 Providing the watch type is required, and other parameters may be required
or supported depending on the watch type. 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) return strings.TrimSpace(helpText)
} }
func (c *WatchCommand) Run(args []string) int { func (c *WatchCommand) Run(args []string) int {
var watchType, datacenter, token, key, prefix, service, tag, passingOnly, stale, state, name string var watchType, key, prefix, service, tag, passingOnly, state, name string
cmdFlags := flag.NewFlagSet("watch", flag.ContinueOnError)
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) } f := c.Command.NewFlagSet(c)
cmdFlags.StringVar(&watchType, "type", "", "") f.StringVar(&watchType, "type", "",
cmdFlags.StringVar(&datacenter, "datacenter", "", "") "Specifies the watch type. One of key, keyprefix services, nodes, "+
cmdFlags.StringVar(&token, "token", "", "") "service, checks, or event.")
cmdFlags.StringVar(&key, "key", "", "") f.StringVar(&key, "key", "",
cmdFlags.StringVar(&prefix, "prefix", "", "") "Specifies the key to watch. Only for 'key' type.")
cmdFlags.StringVar(&service, "service", "", "") f.StringVar(&prefix, "prefix", "",
cmdFlags.StringVar(&tag, "tag", "", "") "Specifies the key prefix to watch. Only for 'keyprefix' type.")
cmdFlags.StringVar(&passingOnly, "passingonly", "", "") f.StringVar(&service, "service", "",
cmdFlags.StringVar(&stale, "stale", "", "") "Specifies the service to watch. Required for 'service' type, "+
cmdFlags.StringVar(&state, "state", "", "") "optional for 'checks' type.")
cmdFlags.StringVar(&name, "name", "", "") f.StringVar(&tag, "tag", "",
httpAddr := HTTPAddrFlag(cmdFlags) "Specifies the service tag to filter on. Optional for 'service' type.")
if err := cmdFlags.Parse(args); err != nil { 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 return 1
} }
@ -87,18 +73,18 @@ func (c *WatchCommand) Run(args []string) int {
} }
// Grab the script to execute if any // Grab the script to execute if any
script := strings.Join(cmdFlags.Args(), " ") script := strings.Join(f.Args(), " ")
// Compile the watch parameters // Compile the watch parameters
params := make(map[string]interface{}) params := make(map[string]interface{})
if watchType != "" { if watchType != "" {
params["type"] = watchType params["type"] = watchType
} }
if datacenter != "" { if c.Command.HTTPDatacenter() != "" {
params["datacenter"] = datacenter params["datacenter"] = c.Command.HTTPDatacenter()
} }
if token != "" { if c.Command.HTTPToken() != "" {
params["token"] = token params["token"] = c.Command.HTTPToken()
} }
if key != "" { if key != "" {
params["key"] = key params["key"] = key
@ -112,13 +98,8 @@ func (c *WatchCommand) Run(args []string) int {
if tag != "" { if tag != "" {
params["tag"] = tag params["tag"] = tag
} }
if stale != "" { if c.Command.HTTPStale() {
b, err := strconv.ParseBool(stale) params["stale"] = c.Command.HTTPStale()
if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to parse stale flag: %s", err))
return 1
}
params["stale"] = b
} }
if state != "" { if state != "" {
params["state"] = state params["state"] = state
@ -143,7 +124,7 @@ func (c *WatchCommand) Run(args []string) int {
} }
// Create and test the HTTP client // Create and test the HTTP client
client, err := HTTPClient(*httpAddr) client, err := c.Command.HTTPClient()
if err != nil { if err != nil {
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
return 1 return 1
@ -213,7 +194,7 @@ func (c *WatchCommand) Run(args []string) int {
}() }()
// Run the watch // 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)) c.Ui.Error(fmt.Sprintf("Error querying Consul agent: %s", err))
return 1 return 1
} }

View File

@ -1,9 +1,11 @@
package command package command
import ( import (
"github.com/mitchellh/cli"
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/consul/command/base"
"github.com/mitchellh/cli"
) )
func TestWatchCommand_implements(t *testing.T) { func TestWatchCommand_implements(t *testing.T) {
@ -15,7 +17,12 @@ func TestWatchCommandRun(t *testing.T) {
defer a1.Shutdown() defer a1.Shutdown()
ui := new(cli.MockUi) 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"} args := []string{"-http-addr=" + a1.httpAddr, "-type=nodes"}
code := c.Run(args) code := c.Run(args)

View File

@ -238,7 +238,10 @@ func init() {
"watch": func() (cli.Command, error) { "watch": func() (cli.Command, error) {
return &command.WatchCommand{ return &command.WatchCommand{
ShutdownCh: makeShutdownCh(), ShutdownCh: makeShutdownCh(),
Ui: ui, Command: base.Command{
Flags: base.FlagSetHTTP,
Ui: ui,
},
}, nil }, nil
}, },
} }

View File

@ -27,18 +27,12 @@ data view. Depending on the type, various options may be required
or optionally provided. There is more documentation on watch or optionally provided. There is more documentation on watch
[specifications here](/docs/agent/watches.html). [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 <%= partial "docs/commands/http_api_options_client" %>
to send this command. If this isn't specified, the command will contact <%= partial "docs/commands/http_api_options_server" %>
"127.0.0.1:8500" which is the default HTTP address of a Consul agent.
* `-datacenter` - Datacenter to query. Defaults to that of the agent. #### Command Options
* `-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.
* `-key` - Key to watch. Only for `key` type. * `-key` - Key to watch. Only for `key` type.