github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/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) clientConfig() *api.Config { 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 config 146 } 147 148 func (m *Meta) Client() (*api.Client, error) { 149 return api.NewClient(m.clientConfig()) 150 } 151 152 func (m *Meta) allNamespaces() bool { 153 return m.clientConfig().Namespace == api.AllNamespacesNamespace 154 } 155 156 func (m *Meta) Colorize() *colorstring.Colorize { 157 return &colorstring.Colorize{ 158 Colors: colorstring.DefaultColors, 159 Disable: m.noColor || !terminal.IsTerminal(int(os.Stdout.Fd())), 160 Reset: true, 161 } 162 } 163 164 type usageOptsFlags uint8 165 166 const ( 167 usageOptsDefault usageOptsFlags = 0 168 usageOptsNoNamespace = 1 << iota 169 ) 170 171 // generalOptionsUsage returns the help string for the global options. 172 func generalOptionsUsage(usageOpts usageOptsFlags) string { 173 174 helpText := ` 175 -address=<addr> 176 The address of the Nomad server. 177 Overrides the NOMAD_ADDR environment variable if set. 178 Default = http://127.0.0.1:4646 179 180 -region=<region> 181 The region of the Nomad servers to forward commands to. 182 Overrides the NOMAD_REGION environment variable if set. 183 Defaults to the Agent's local region. 184 ` 185 186 namespaceText := ` 187 -namespace=<namespace> 188 The target namespace for queries and actions bound to a namespace. 189 Overrides the NOMAD_NAMESPACE environment variable if set. 190 If set to '*', job and alloc subcommands query all namespaces authorized 191 to user. 192 Defaults to the "default" namespace. 193 ` 194 195 // note: that although very few commands use color explicitly, all of them 196 // return red-colored text on error so we don't want to make this 197 // configurable 198 remainingText := ` 199 -no-color 200 Disables colored command output. Alternatively, NOMAD_CLI_NO_COLOR may be 201 set. 202 203 -ca-cert=<path> 204 Path to a PEM encoded CA cert file to use to verify the 205 Nomad server SSL certificate. Overrides the NOMAD_CACERT 206 environment variable if set. 207 208 -ca-path=<path> 209 Path to a directory of PEM encoded CA cert files to verify 210 the Nomad server SSL certificate. If both -ca-cert and 211 -ca-path are specified, -ca-cert is used. Overrides the 212 NOMAD_CAPATH environment variable if set. 213 214 -client-cert=<path> 215 Path to a PEM encoded client certificate for TLS authentication 216 to the Nomad server. Must also specify -client-key. Overrides 217 the NOMAD_CLIENT_CERT environment variable if set. 218 219 -client-key=<path> 220 Path to an unencrypted PEM encoded private key matching the 221 client certificate from -client-cert. Overrides the 222 NOMAD_CLIENT_KEY environment variable if set. 223 224 -tls-server-name=<value> 225 The server name to use as the SNI host when connecting via 226 TLS. Overrides the NOMAD_TLS_SERVER_NAME environment variable if set. 227 228 -tls-skip-verify 229 Do not verify TLS certificate. This is highly not recommended. Verification 230 will also be skipped if NOMAD_SKIP_VERIFY is set. 231 232 -token 233 The SecretID of an ACL token to use to authenticate API requests with. 234 Overrides the NOMAD_TOKEN environment variable if set. 235 ` 236 237 if usageOpts&usageOptsNoNamespace == 0 { 238 helpText = helpText + namespaceText 239 } 240 241 helpText = helpText + remainingText 242 return strings.TrimSpace(helpText) 243 } 244 245 // funcVar is a type of flag that accepts a function that is the string given 246 // by the user. 247 type funcVar func(s string) error 248 249 func (f funcVar) Set(s string) error { return f(s) } 250 func (f funcVar) String() string { return "" } 251 func (f funcVar) IsBoolFlag() bool { return false }