2016-02-19 17:42:51 -05:00
package flags
import (
"fmt"
"os"
"path/filepath"
2022-03-04 07:24:28 -05:00
"github.com/docker/cli/cli/config"
2017-05-15 08:45:19 -04:00
"github.com/docker/cli/opts"
2022-03-24 19:15:14 -04:00
"github.com/docker/docker/client"
2016-02-19 17:42:51 -05:00
"github.com/docker/go-connections/tlsconfig"
2017-08-07 05:52:40 -04:00
"github.com/sirupsen/logrus"
2016-06-21 16:42:47 -04:00
"github.com/spf13/pflag"
2016-02-19 17:42:51 -05:00
)
const (
2023-06-28 07:56:24 -04:00
// EnvEnableTLS is the name of the environment variable that can be used
// to enable TLS for client connections. When set to a non-empty value, TLS
// is enabled for API connections using TCP. For backward-compatibility, this
// environment-variable can only be used to enable TLS, not to disable.
//
// Note that TLS is always enabled implicitly if the "--tls-verify" option
// or "DOCKER_TLS_VERIFY" ([github.com/docker/docker/client.EnvTLSVerify])
// env var is set to, which could be to either enable or disable TLS certification
// validation. In both cases, TLS is enabled but, depending on the setting,
// with verification disabled.
EnvEnableTLS = "DOCKER_TLS"
2016-02-19 17:42:51 -05:00
// DefaultCaFile is the default filename for the CA pem file
DefaultCaFile = "ca.pem"
// DefaultKeyFile is the default filename for the key pem file
DefaultKeyFile = "key.pem"
// DefaultCertFile is the default filename for the cert pem file
DefaultCertFile = "cert.pem"
2016-12-20 06:14:41 -05:00
// FlagTLSVerify is the flag name for the TLS verification option
2016-06-21 16:42:47 -04:00
FlagTLSVerify = "tlsverify"
2021-03-09 18:45:56 -05:00
// FormatHelp describes the --format flag behavior for list commands
FormatHelp = ` Format output using a custom template :
' table ' : Print output in table format with column headers ( default )
' table TEMPLATE ' : Print output in table format using the given Go template
' json ' : Print in JSON format
' TEMPLATE ' : Print output using the given Go template .
Refer to https : //docs.docker.com/go/formatting/ for more information about formatting output with templates`
2021-01-18 05:43:29 -05:00
// InspectFormatHelp describes the --format flag behavior for inspect commands
InspectFormatHelp = ` Format output using a custom template :
' json ' : Print in JSON format
' TEMPLATE ' : Print output using the given Go template .
Refer to https : //docs.docker.com/go/formatting/ for more information about formatting output with templates`
2016-02-19 17:42:51 -05:00
)
var (
2022-03-24 19:15:14 -04:00
dockerCertPath = os . Getenv ( client . EnvOverrideCertPath )
dockerTLSVerify = os . Getenv ( client . EnvTLSVerify ) != ""
2023-06-28 07:56:24 -04:00
dockerTLS = os . Getenv ( EnvEnableTLS ) != ""
2016-02-19 17:42:51 -05:00
)
2022-11-04 06:58:11 -04:00
// ClientOptions are the options used to configure the client cli.
type ClientOptions struct {
2018-06-20 08:48:50 -04:00
Debug bool
Hosts [ ] string
LogLevel string
TLS bool
TLSVerify bool
TLSOptions * tlsconfig . Options
2018-12-17 05:27:07 -05:00
Context string
2022-11-04 06:58:11 -04:00
ConfigDir string
2016-04-21 17:51:28 -04:00
}
2022-11-04 06:58:11 -04:00
// NewClientOptions returns a new ClientOptions.
func NewClientOptions ( ) * ClientOptions {
return & ClientOptions { }
2016-06-21 16:42:47 -04:00
}
2016-02-19 17:42:51 -05:00
2016-06-21 16:42:47 -04:00
// InstallFlags adds flags for the common options on the FlagSet
2022-11-04 06:58:11 -04:00
func ( o * ClientOptions ) InstallFlags ( flags * pflag . FlagSet ) {
2023-06-28 09:40:42 -04:00
configDir := config . Dir ( )
2016-02-19 17:42:51 -05:00
if dockerCertPath == "" {
2023-06-28 09:40:42 -04:00
dockerCertPath = configDir
2016-02-19 17:42:51 -05:00
}
2023-06-28 09:40:42 -04:00
flags . StringVar ( & o . ConfigDir , "config" , configDir , "Location of client config files" )
2022-11-04 06:58:11 -04:00
flags . BoolVarP ( & o . Debug , "debug" , "D" , false , "Enable debug mode" )
2023-01-03 05:12:24 -05:00
flags . StringVarP ( & o . LogLevel , "log-level" , "l" , "info" , ` Set the logging level ("debug", "info", "warn", "error", "fatal") ` )
2022-11-04 06:58:11 -04:00
flags . BoolVar ( & o . TLS , "tls" , dockerTLS , "Use TLS; implied by --tlsverify" )
flags . BoolVar ( & o . TLSVerify , FlagTLSVerify , dockerTLSVerify , "Use TLS and verify the remote" )
2016-02-19 17:42:51 -05:00
2022-11-04 06:58:11 -04:00
o . TLSOptions = & tlsconfig . Options {
2017-01-03 15:58:41 -05:00
CAFile : filepath . Join ( dockerCertPath , DefaultCaFile ) ,
CertFile : filepath . Join ( dockerCertPath , DefaultCertFile ) ,
KeyFile : filepath . Join ( dockerCertPath , DefaultKeyFile ) ,
}
2022-11-04 06:58:11 -04:00
tlsOptions := o . TLSOptions
2017-01-03 15:58:41 -05:00
flags . Var ( opts . NewQuotedString ( & tlsOptions . CAFile ) , "tlscacert" , "Trust certs signed only by this CA" )
flags . Var ( opts . NewQuotedString ( & tlsOptions . CertFile ) , "tlscert" , "Path to TLS certificate file" )
flags . Var ( opts . NewQuotedString ( & tlsOptions . KeyFile ) , "tlskey" , "Path to TLS key file" )
2016-02-19 17:42:51 -05:00
2018-02-19 04:31:29 -05:00
// opts.ValidateHost is not used here, so as to allow connection helpers
2022-11-04 06:58:11 -04:00
hostOpt := opts . NewNamedListOptsRef ( "hosts" , & o . Hosts , nil )
2023-05-05 10:47:16 -04:00
flags . VarP ( hostOpt , "host" , "H" , "Daemon socket to connect to" )
2022-11-04 06:58:11 -04:00
flags . StringVarP ( & o . Context , "context" , "c" , "" ,
2022-03-24 19:15:14 -04:00
` Name of the context to use to connect to the daemon (overrides ` + client . EnvOverrideHost + ` env var and default context set with "docker context use") ` )
2016-02-19 17:42:51 -05:00
}
2016-06-21 16:42:47 -04:00
// SetDefaultOptions sets default values for options after flag parsing is
// complete
2022-11-04 06:58:11 -04:00
func ( o * ClientOptions ) SetDefaultOptions ( flags * pflag . FlagSet ) {
2016-02-19 17:42:51 -05:00
// Regardless of whether the user sets it to true or false, if they
2016-12-20 06:14:41 -05:00
// specify --tlsverify at all then we need to turn on TLS
2016-02-19 17:42:51 -05:00
// TLSVerify can be true even if not set due to DOCKER_TLS_VERIFY env var, so we need
// to check that here as well
2022-11-04 06:58:11 -04:00
if flags . Changed ( FlagTLSVerify ) || o . TLSVerify {
o . TLS = true
2016-02-19 17:42:51 -05:00
}
2022-11-04 06:58:11 -04:00
if ! o . TLS {
o . TLSOptions = nil
2016-02-19 17:42:51 -05:00
} else {
2022-11-04 06:58:11 -04:00
tlsOptions := o . TLSOptions
tlsOptions . InsecureSkipVerify = ! o . TLSVerify
2016-02-19 17:42:51 -05:00
// Reset CertFile and KeyFile to empty string if the user did not specify
// the respective flags and the respective default files were not found.
2016-06-21 16:42:47 -04:00
if ! flags . Changed ( "tlscert" ) {
2016-02-19 17:42:51 -05:00
if _ , err := os . Stat ( tlsOptions . CertFile ) ; os . IsNotExist ( err ) {
tlsOptions . CertFile = ""
}
}
2016-06-21 16:42:47 -04:00
if ! flags . Changed ( "tlskey" ) {
2016-02-19 17:42:51 -05:00
if _ , err := os . Stat ( tlsOptions . KeyFile ) ; os . IsNotExist ( err ) {
tlsOptions . KeyFile = ""
}
}
}
}
2016-10-11 07:35:12 -04:00
// SetLogLevel sets the logrus logging level
func SetLogLevel ( logLevel string ) {
2016-02-19 17:42:51 -05:00
if logLevel != "" {
lvl , err := logrus . ParseLevel ( logLevel )
if err != nil {
fmt . Fprintf ( os . Stderr , "Unable to parse logging level: %s\n" , logLevel )
os . Exit ( 1 )
}
logrus . SetLevel ( lvl )
} else {
logrus . SetLevel ( logrus . InfoLevel )
}
}