commands: move flag handling into flags pkg
This commit is contained in:
parent
f8eb4006fa
commit
e65bd2a268
|
@ -9,7 +9,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/configutil"
|
||||
"github.com/hashicorp/consul/command/flags"
|
||||
"github.com/mitchellh/cli"
|
||||
text "github.com/tonnerre/golang-text"
|
||||
)
|
||||
|
@ -39,16 +39,16 @@ type BaseCommand struct {
|
|||
hidden *flag.FlagSet
|
||||
|
||||
// These are the options which correspond to the HTTP API options
|
||||
httpAddr configutil.StringValue
|
||||
token configutil.StringValue
|
||||
caFile configutil.StringValue
|
||||
caPath configutil.StringValue
|
||||
certFile configutil.StringValue
|
||||
keyFile configutil.StringValue
|
||||
tlsServerName configutil.StringValue
|
||||
httpAddr flags.StringValue
|
||||
token flags.StringValue
|
||||
caFile flags.StringValue
|
||||
caPath flags.StringValue
|
||||
certFile flags.StringValue
|
||||
keyFile flags.StringValue
|
||||
tlsServerName flags.StringValue
|
||||
|
||||
datacenter configutil.StringValue
|
||||
stale configutil.BoolValue
|
||||
datacenter flags.StringValue
|
||||
stale flags.BoolValue
|
||||
}
|
||||
|
||||
// HTTPClient returns a client with the parsed flags. It panics if the command
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/configutil"
|
||||
"github.com/hashicorp/consul/command/flags"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/ryanuber/columnize"
|
||||
)
|
||||
|
@ -31,7 +31,7 @@ func (c *CatalogListNodesCommand) initFlags() {
|
|||
c.FlagSet.StringVar(&c.near, "near", "", "Node name to sort the node list in ascending "+
|
||||
"order based on estimated round-trip time from that node. "+
|
||||
"Passing \"_agent\" will use this agent's node for sorting.")
|
||||
c.FlagSet.Var((*configutil.FlagMapValue)(&c.nodeMeta), "node-meta", "Metadata to "+
|
||||
c.FlagSet.Var((*flags.FlagMapValue)(&c.nodeMeta), "node-meta", "Metadata to "+
|
||||
"filter nodes with the given `key=value` pairs. This flag may be "+
|
||||
"specified multiple times to filter on multiple sources of metadata.")
|
||||
c.FlagSet.StringVar(&c.service, "service", "", "Service `id or name` to filter nodes. "+
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"text/tabwriter"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/configutil"
|
||||
"github.com/hashicorp/consul/command/flags"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
|
@ -29,7 +29,7 @@ func (c *CatalogListServicesCommand) initFlags() {
|
|||
c.InitFlagSet()
|
||||
c.FlagSet.StringVar(&c.node, "node", "",
|
||||
"Node `id or name` for which to list services.")
|
||||
c.FlagSet.Var((*configutil.FlagMapValue)(&c.nodeMeta), "node-meta", "Metadata to "+
|
||||
c.FlagSet.Var((*flags.FlagMapValue)(&c.nodeMeta), "node-meta", "Metadata to "+
|
||||
"filter nodes with the given `key=value` pairs. If specified, only "+
|
||||
"services running on nodes matching the given metadata will be returned. "+
|
||||
"This flag may be specified multiple times to filter on multiple sources "+
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package configutil
|
||||
package flags
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -1,14 +1,13 @@
|
|||
package configutil
|
||||
package flags
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"path"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
@ -108,7 +107,7 @@ func TestConfigUtil_Visit(t *testing.T) {
|
|||
return nil
|
||||
}
|
||||
|
||||
basePath := "../test/command/merge"
|
||||
basePath := "../../test/command/merge"
|
||||
if err := Visit(basePath, visitor); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package configutil
|
||||
package flags
|
||||
|
||||
import (
|
||||
"flag"
|
|
@ -1,4 +1,4 @@
|
|||
package configutil
|
||||
package flags
|
||||
|
||||
import (
|
||||
"fmt"
|
|
@ -1,4 +1,4 @@
|
|||
package configutil
|
||||
package flags
|
||||
|
||||
import "strings"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package configutil
|
||||
package flags
|
||||
|
||||
import (
|
||||
"flag"
|
|
@ -0,0 +1,92 @@
|
|||
package flags
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
type HTTPFlags struct {
|
||||
// client api flags
|
||||
address StringValue
|
||||
token StringValue
|
||||
caFile StringValue
|
||||
caPath StringValue
|
||||
certFile StringValue
|
||||
keyFile StringValue
|
||||
tlsServerName StringValue
|
||||
|
||||
// server flags
|
||||
datacenter StringValue
|
||||
stale BoolValue
|
||||
}
|
||||
|
||||
func (f *HTTPFlags) ClientFlags() *flag.FlagSet {
|
||||
fs := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fs.Var(&f.address, "http-addr",
|
||||
"The `address` and port of the Consul HTTP agent. The value can be an IP "+
|
||||
"address or DNS address, but it must also include the port. This can "+
|
||||
"also be specified via the CONSUL_HTTP_ADDR environment variable. The "+
|
||||
"default value is http://127.0.0.1:8500. The scheme can also be set to "+
|
||||
"HTTPS by setting the environment variable CONSUL_HTTP_SSL=true.")
|
||||
fs.Var(&f.token, "token",
|
||||
"ACL token to use in the request. This can also be specified via the "+
|
||||
"CONSUL_HTTP_TOKEN environment variable. If unspecified, the query will "+
|
||||
"default to the token of the Consul agent at the HTTP address.")
|
||||
fs.Var(&f.caFile, "ca-file",
|
||||
"Path to a CA file to use for TLS when communicating with Consul. This "+
|
||||
"can also be specified via the CONSUL_CACERT environment variable.")
|
||||
fs.Var(&f.caPath, "ca-path",
|
||||
"Path to a directory of CA certificates to use for TLS when communicating "+
|
||||
"with Consul. This can also be specified via the CONSUL_CAPATH environment variable.")
|
||||
fs.Var(&f.certFile, "client-cert",
|
||||
"Path to a client cert file to use for TLS when 'verify_incoming' is enabled. This "+
|
||||
"can also be specified via the CONSUL_CLIENT_CERT environment variable.")
|
||||
fs.Var(&f.keyFile, "client-key",
|
||||
"Path to a client key file to use for TLS when 'verify_incoming' is enabled. This "+
|
||||
"can also be specified via the CONSUL_CLIENT_KEY environment variable.")
|
||||
fs.Var(&f.tlsServerName, "tls-server-name",
|
||||
"The server name to use as the SNI host when connecting via TLS. This "+
|
||||
"can also be specified via the CONSUL_TLS_SERVER_NAME environment variable.")
|
||||
|
||||
return fs
|
||||
}
|
||||
|
||||
func (f *HTTPFlags) ServerFlags() *flag.FlagSet {
|
||||
fs := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fs.Var(&f.datacenter, "datacenter",
|
||||
"Name of the datacenter to query. If unspecified, this will default to "+
|
||||
"the datacenter of the queried agent.")
|
||||
fs.Var(&f.stale, "stale",
|
||||
"Permit any Consul server (non-leader) to respond to this request. This "+
|
||||
"allows for lower latency and higher throughput, but can result in "+
|
||||
"stale data. This option has no effect on non-read operations. The "+
|
||||
"default value is false.")
|
||||
return fs
|
||||
}
|
||||
|
||||
func (f *HTTPFlags) Datacenter() string {
|
||||
return f.datacenter.String()
|
||||
}
|
||||
|
||||
func (f *HTTPFlags) Stale() bool {
|
||||
if f.stale.v == nil {
|
||||
return false
|
||||
}
|
||||
return *f.stale.v
|
||||
}
|
||||
|
||||
func (f *HTTPFlags) APIClient() (*api.Client, error) {
|
||||
c := api.DefaultConfig()
|
||||
|
||||
f.address.Merge(&c.Address)
|
||||
f.token.Merge(&c.Token)
|
||||
f.caFile.Merge(&c.TLSConfig.CAFile)
|
||||
f.caPath.Merge(&c.TLSConfig.CAPath)
|
||||
f.certFile.Merge(&c.TLSConfig.CertFile)
|
||||
f.keyFile.Merge(&c.TLSConfig.KeyFile)
|
||||
f.tlsServerName.Merge(&c.TLSConfig.Address)
|
||||
f.datacenter.Merge(&c.Datacenter)
|
||||
|
||||
return api.NewClient(c)
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package flags
|
||||
|
||||
import "flag"
|
||||
|
||||
func Merge(dst, src *flag.FlagSet) {
|
||||
if dst == nil {
|
||||
panic("dst cannot be nil")
|
||||
}
|
||||
if src == nil {
|
||||
return
|
||||
}
|
||||
src.VisitAll(func(f *flag.Flag) {
|
||||
dst.Var(f.Value, f.Name, f.DefValue)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package flags
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
text "github.com/tonnerre/golang-text"
|
||||
)
|
||||
|
||||
func Usage(txt string, cmdFlags, clientFlags, serverFlags *flag.FlagSet) string {
|
||||
u := &Usager{
|
||||
Usage: txt,
|
||||
CmdFlags: cmdFlags,
|
||||
HTTPClientFlags: clientFlags,
|
||||
HTTPServerFlags: serverFlags,
|
||||
}
|
||||
return u.String()
|
||||
}
|
||||
|
||||
type Usager struct {
|
||||
Usage string
|
||||
CmdFlags *flag.FlagSet
|
||||
HTTPClientFlags *flag.FlagSet
|
||||
HTTPServerFlags *flag.FlagSet
|
||||
}
|
||||
|
||||
func (u *Usager) String() string {
|
||||
out := new(bytes.Buffer)
|
||||
out.WriteString(strings.TrimSpace(u.Usage))
|
||||
out.WriteString("\n")
|
||||
out.WriteString("\n")
|
||||
|
||||
httpFlags := u.HTTPClientFlags
|
||||
if httpFlags == nil {
|
||||
httpFlags = u.HTTPServerFlags
|
||||
} else {
|
||||
Merge(httpFlags, u.HTTPServerFlags)
|
||||
}
|
||||
|
||||
if httpFlags != nil {
|
||||
printTitle(out, "HTTP API Options")
|
||||
httpFlags.VisitAll(func(f *flag.Flag) {
|
||||
printFlag(out, f)
|
||||
})
|
||||
}
|
||||
|
||||
if u.CmdFlags != nil {
|
||||
printTitle(out, "Command Options")
|
||||
u.CmdFlags.VisitAll(func(f *flag.Flag) {
|
||||
if flagContains(httpFlags, f) {
|
||||
return
|
||||
}
|
||||
printFlag(out, f)
|
||||
})
|
||||
}
|
||||
|
||||
return strings.TrimRight(out.String(), "\n")
|
||||
}
|
||||
|
||||
// printTitle prints a consistently-formatted title to the given writer.
|
||||
func printTitle(w io.Writer, s string) {
|
||||
fmt.Fprintf(w, "%s\n\n", s)
|
||||
}
|
||||
|
||||
// printFlag prints a single flag to the given writer.
|
||||
func printFlag(w io.Writer, f *flag.Flag) {
|
||||
example, _ := flag.UnquoteUsage(f)
|
||||
if example != "" {
|
||||
fmt.Fprintf(w, " -%s=<%s>\n", f.Name, example)
|
||||
} else {
|
||||
fmt.Fprintf(w, " -%s\n", f.Name)
|
||||
}
|
||||
|
||||
indented := wrapAtLength(f.Usage, 5)
|
||||
fmt.Fprintf(w, "%s\n\n", indented)
|
||||
}
|
||||
|
||||
// flagContains returns true if the given flag is contained in the given flag
|
||||
// set or false otherwise.
|
||||
func flagContains(fs *flag.FlagSet, f *flag.Flag) bool {
|
||||
if fs == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var skip bool
|
||||
fs.VisitAll(func(hf *flag.Flag) {
|
||||
if skip {
|
||||
return
|
||||
}
|
||||
|
||||
if f.Name == hf.Name {
|
||||
skip = true
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
return skip
|
||||
}
|
||||
|
||||
// maxLineLength is the maximum width of any line.
|
||||
const maxLineLength int = 72
|
||||
|
||||
// wrapAtLength wraps the given text at the maxLineLength, taking into account
|
||||
// any provided left padding.
|
||||
func wrapAtLength(s string, pad int) string {
|
||||
wrapped := text.Wrap(s, maxLineLength-pad)
|
||||
lines := strings.Split(wrapped, "\n")
|
||||
for i, line := range lines {
|
||||
lines[i] = strings.Repeat(" ", pad) + line
|
||||
}
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
|
@ -6,20 +6,20 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/hashicorp/consul/configutil"
|
||||
"github.com/hashicorp/consul/command/flags"
|
||||
)
|
||||
|
||||
type OperatorAutopilotSetCommand struct {
|
||||
BaseCommand
|
||||
|
||||
// flags
|
||||
cleanupDeadServers configutil.BoolValue
|
||||
maxTrailingLogs configutil.UintValue
|
||||
lastContactThreshold configutil.DurationValue
|
||||
serverStabilizationTime configutil.DurationValue
|
||||
redundancyZoneTag configutil.StringValue
|
||||
disableUpgradeMigration configutil.BoolValue
|
||||
upgradeVersionTag configutil.StringValue
|
||||
cleanupDeadServers flags.BoolValue
|
||||
maxTrailingLogs flags.UintValue
|
||||
lastContactThreshold flags.DurationValue
|
||||
serverStabilizationTime flags.DurationValue
|
||||
redundancyZoneTag flags.StringValue
|
||||
disableUpgradeMigration flags.BoolValue
|
||||
upgradeVersionTag flags.StringValue
|
||||
}
|
||||
|
||||
func (c *OperatorAutopilotSetCommand) initFlags() {
|
||||
|
|
Loading…
Reference in New Issue