github.com/ThomasObenaus/nomad@v0.11.1/command/meta.go (about) 1 package command 2 3 import ( 4 "flag" 5 "os" 6 "strings" 7 8 "github.com/hashicorp/nomad/api" 9 "github.com/mitchellh/cli" 10 "github.com/mitchellh/colorstring" 11 "github.com/posener/complete" 12 "golang.org/x/crypto/ssh/terminal" 13 ) 14 15 const ( 16 // Constants for CLI identifier length 17 shortId = 8 18 fullId = 36 19 ) 20 21 // FlagSetFlags is an enum to define what flags are present in the 22 // default FlagSet returned by Meta.FlagSet. 23 type FlagSetFlags uint 24 25 const ( 26 FlagSetNone FlagSetFlags = 0 27 FlagSetClient FlagSetFlags = 1 << iota 28 FlagSetDefault = FlagSetClient 29 ) 30 31 // Meta contains the meta-options and functionality that nearly every 32 // Nomad command inherits. 33 type Meta struct { 34 Ui cli.Ui 35 36 // These are set by the command line flags. 37 flagAddress string 38 39 // Whether to not-colorize output 40 noColor bool 41 42 // The region to send API requests 43 region string 44 45 // namespace to send API requests 46 namespace string 47 48 // token is used for ACLs to access privileged information 49 token string 50 51 caCert string 52 caPath string 53 clientCert string 54 clientKey string 55 tlsServerName string 56 insecure bool 57 } 58 59 // FlagSet returns a FlagSet with the common flags that every 60 // command implements. The exact behavior of FlagSet can be configured 61 // using the flags as the second parameter, for example to disable 62 // server settings on the commands that don't talk to a server. 63 func (m *Meta) FlagSet(n string, fs FlagSetFlags) *flag.FlagSet { 64 f := flag.NewFlagSet(n, flag.ContinueOnError) 65 66 // FlagSetClient is used to enable the settings for specifying 67 // client connectivity options. 68 if fs&FlagSetClient != 0 { 69 f.StringVar(&m.flagAddress, "address", "", "") 70 f.StringVar(&m.region, "region", "", "") 71 f.StringVar(&m.namespace, "namespace", "", "") 72 f.BoolVar(&m.noColor, "no-color", false, "") 73 f.StringVar(&m.caCert, "ca-cert", "", "") 74 f.StringVar(&m.caPath, "ca-path", "", "") 75 f.StringVar(&m.clientCert, "client-cert", "", "") 76 f.StringVar(&m.clientKey, "client-key", "", "") 77 f.BoolVar(&m.insecure, "insecure", false, "") 78 f.StringVar(&m.tlsServerName, "tls-server-name", "", "") 79 f.BoolVar(&m.insecure, "tls-skip-verify", false, "") 80 f.StringVar(&m.token, "token", "", "") 81 82 } 83 84 f.SetOutput(&uiErrorWriter{ui: m.Ui}) 85 86 return f 87 } 88 89 // AutocompleteFlags returns a set of flag completions for the given flag set. 90 func (m *Meta) AutocompleteFlags(fs FlagSetFlags) complete.Flags { 91 if fs&FlagSetClient == 0 { 92 return nil 93 } 94 95 return complete.Flags{ 96 "-address": complete.PredictAnything, 97 "-region": complete.PredictAnything, 98 "-namespace": NamespacePredictor(m.Client, nil), 99 "-no-color": complete.PredictNothing, 100 "-ca-cert": complete.PredictFiles("*"), 101 "-ca-path": complete.PredictDirs("*"), 102 "-client-cert": complete.PredictFiles("*"), 103 "-client-key": complete.PredictFiles("*"), 104 "-insecure": complete.PredictNothing, 105 "-tls-server-name": complete.PredictNothing, 106 "-tls-skip-verify": complete.PredictNothing, 107 "-token": complete.PredictAnything, 108 } 109 } 110 111 // ApiClientFactory is the signature of a API client factory 112 type ApiClientFactory func() (*api.Client, error) 113 114 // Client is used to initialize and return a new API client using 115 // the default command line arguments and env vars. 116 func (m *Meta) Client() (*api.Client, error) { 117 config := api.DefaultConfig() 118 if m.flagAddress != "" { 119 config.Address = m.flagAddress 120 } 121 if m.region != "" { 122 config.Region = m.region 123 } 124 if m.namespace != "" { 125 config.Namespace = m.namespace 126 } 127 128 // If we need custom TLS configuration, then set it 129 if m.caCert != "" || m.caPath != "" || m.clientCert != "" || m.clientKey != "" || m.tlsServerName != "" || m.insecure { 130 t := &api.TLSConfig{ 131 CACert: m.caCert, 132 CAPath: m.caPath, 133 ClientCert: m.clientCert, 134 ClientKey: m.clientKey, 135 TLSServerName: m.tlsServerName, 136 Insecure: m.insecure, 137 } 138 config.TLSConfig = t 139 } 140 141 if m.token != "" { 142 config.SecretID = m.token 143 } 144 145 return api.NewClient(config) 146 } 147 148 func (m *Meta) Colorize() *colorstring.Colorize { 149 return &colorstring.Colorize{ 150 Colors: colorstring.DefaultColors, 151 Disable: m.noColor || !terminal.IsTerminal(int(os.Stdout.Fd())), 152 Reset: true, 153 } 154 } 155 156 // generalOptionsUsage returns the help string for the global options. 157 func generalOptionsUsage() string { 158 helpText := ` 159 -address=<addr> 160 The address of the Nomad server. 161 Overrides the NOMAD_ADDR environment variable if set. 162 Default = http://127.0.0.1:4646 163 164 -region=<region> 165 The region of the Nomad servers to forward commands to. 166 Overrides the NOMAD_REGION environment variable if set. 167 Defaults to the Agent's local region. 168 169 -namespace=<namespace> 170 The target namespace for queries and actions bound to a namespace. 171 Overrides the NOMAD_NAMESPACE environment variable if set. 172 Defaults to the "default" namespace. 173 174 -no-color 175 Disables colored command output. Alternatively, NOMAD_CLI_NO_COLOR may be 176 set. 177 178 -ca-cert=<path> 179 Path to a PEM encoded CA cert file to use to verify the 180 Nomad server SSL certificate. Overrides the NOMAD_CACERT 181 environment variable if set. 182 183 -ca-path=<path> 184 Path to a directory of PEM encoded CA cert files to verify 185 the Nomad server SSL certificate. If both -ca-cert and 186 -ca-path are specified, -ca-cert is used. Overrides the 187 NOMAD_CAPATH environment variable if set. 188 189 -client-cert=<path> 190 Path to a PEM encoded client certificate for TLS authentication 191 to the Nomad server. Must also specify -client-key. Overrides 192 the NOMAD_CLIENT_CERT environment variable if set. 193 194 -client-key=<path> 195 Path to an unencrypted PEM encoded private key matching the 196 client certificate from -client-cert. Overrides the 197 NOMAD_CLIENT_KEY environment variable if set. 198 199 -tls-server-name=<value> 200 The server name to use as the SNI host when connecting via 201 TLS. Overrides the NOMAD_TLS_SERVER_NAME environment variable if set. 202 203 -tls-skip-verify 204 Do not verify TLS certificate. This is highly not recommended. Verification 205 will also be skipped if NOMAD_SKIP_VERIFY is set. 206 207 -token 208 The SecretID of an ACL token to use to authenticate API requests with. 209 Overrides the NOMAD_TOKEN environment variable if set. 210 ` 211 return strings.TrimSpace(helpText) 212 } 213 214 // funcVar is a type of flag that accepts a function that is the string given 215 // by the user. 216 type funcVar func(s string) error 217 218 func (f funcVar) Set(s string) error { return f(s) } 219 func (f funcVar) String() string { return "" } 220 func (f funcVar) IsBoolFlag() bool { return false }