1package flags 2 3import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 8 cliconfig "github.com/docker/cli/cli/config" 9 "github.com/docker/cli/opts" 10 "github.com/docker/go-connections/tlsconfig" 11 "github.com/sirupsen/logrus" 12 "github.com/spf13/pflag" 13) 14 15const ( 16 // DefaultCaFile is the default filename for the CA pem file 17 DefaultCaFile = "ca.pem" 18 // DefaultKeyFile is the default filename for the key pem file 19 DefaultKeyFile = "key.pem" 20 // DefaultCertFile is the default filename for the cert pem file 21 DefaultCertFile = "cert.pem" 22 // FlagTLSVerify is the flag name for the TLS verification option 23 FlagTLSVerify = "tlsverify" 24) 25 26var ( 27 dockerCertPath = os.Getenv("DOCKER_CERT_PATH") 28 dockerTLSVerify = os.Getenv("DOCKER_TLS_VERIFY") != "" 29 dockerTLS = os.Getenv("DOCKER_TLS") != "" 30) 31 32// CommonOptions are options common to both the client and the daemon. 33type CommonOptions struct { 34 Debug bool 35 Hosts []string 36 LogLevel string 37 TLS bool 38 TLSVerify bool 39 TLSOptions *tlsconfig.Options 40} 41 42// NewCommonOptions returns a new CommonOptions 43func NewCommonOptions() *CommonOptions { 44 return &CommonOptions{} 45} 46 47// InstallFlags adds flags for the common options on the FlagSet 48func (commonOpts *CommonOptions) InstallFlags(flags *pflag.FlagSet) { 49 if dockerCertPath == "" { 50 dockerCertPath = cliconfig.Dir() 51 } 52 53 flags.BoolVarP(&commonOpts.Debug, "debug", "D", false, "Enable debug mode") 54 flags.StringVarP(&commonOpts.LogLevel, "log-level", "l", "info", `Set the logging level ("debug"|"info"|"warn"|"error"|"fatal")`) 55 flags.BoolVar(&commonOpts.TLS, "tls", dockerTLS, "Use TLS; implied by --tlsverify") 56 flags.BoolVar(&commonOpts.TLSVerify, FlagTLSVerify, dockerTLSVerify, "Use TLS and verify the remote") 57 58 // TODO use flag flags.String("identity"}, "i", "", "Path to libtrust key file") 59 60 commonOpts.TLSOptions = &tlsconfig.Options{ 61 CAFile: filepath.Join(dockerCertPath, DefaultCaFile), 62 CertFile: filepath.Join(dockerCertPath, DefaultCertFile), 63 KeyFile: filepath.Join(dockerCertPath, DefaultKeyFile), 64 } 65 tlsOptions := commonOpts.TLSOptions 66 flags.Var(opts.NewQuotedString(&tlsOptions.CAFile), "tlscacert", "Trust certs signed only by this CA") 67 flags.Var(opts.NewQuotedString(&tlsOptions.CertFile), "tlscert", "Path to TLS certificate file") 68 flags.Var(opts.NewQuotedString(&tlsOptions.KeyFile), "tlskey", "Path to TLS key file") 69 70 // opts.ValidateHost is not used here, so as to allow connection helpers 71 hostOpt := opts.NewNamedListOptsRef("hosts", &commonOpts.Hosts, nil) 72 flags.VarP(hostOpt, "host", "H", "Daemon socket(s) to connect to") 73} 74 75// SetDefaultOptions sets default values for options after flag parsing is 76// complete 77func (commonOpts *CommonOptions) SetDefaultOptions(flags *pflag.FlagSet) { 78 // Regardless of whether the user sets it to true or false, if they 79 // specify --tlsverify at all then we need to turn on TLS 80 // TLSVerify can be true even if not set due to DOCKER_TLS_VERIFY env var, so we need 81 // to check that here as well 82 if flags.Changed(FlagTLSVerify) || commonOpts.TLSVerify { 83 commonOpts.TLS = true 84 } 85 86 if !commonOpts.TLS { 87 commonOpts.TLSOptions = nil 88 } else { 89 tlsOptions := commonOpts.TLSOptions 90 tlsOptions.InsecureSkipVerify = !commonOpts.TLSVerify 91 92 // Reset CertFile and KeyFile to empty string if the user did not specify 93 // the respective flags and the respective default files were not found. 94 if !flags.Changed("tlscert") { 95 if _, err := os.Stat(tlsOptions.CertFile); os.IsNotExist(err) { 96 tlsOptions.CertFile = "" 97 } 98 } 99 if !flags.Changed("tlskey") { 100 if _, err := os.Stat(tlsOptions.KeyFile); os.IsNotExist(err) { 101 tlsOptions.KeyFile = "" 102 } 103 } 104 } 105} 106 107// SetLogLevel sets the logrus logging level 108func SetLogLevel(logLevel string) { 109 if logLevel != "" { 110 lvl, err := logrus.ParseLevel(logLevel) 111 if err != nil { 112 fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", logLevel) 113 os.Exit(1) 114 } 115 logrus.SetLevel(lvl) 116 } else { 117 logrus.SetLevel(logrus.InfoLevel) 118 } 119} 120