Fix post config verification without flags.
- Set the daemon log level to what's set in the configuration. - Enable TLS when TLSVerify is enabled. Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
parent
30e42a2799
commit
cd3446972e
4 changed files with 176 additions and 19 deletions
|
@ -84,6 +84,7 @@ type CommonConfig struct {
|
|||
TLSOptions CommonTLSOptions `json:"tls-opts,omitempty"`
|
||||
|
||||
reloadLock sync.Mutex
|
||||
valuesSet map[string]interface{}
|
||||
}
|
||||
|
||||
// InstallCommonFlags adds command-line options to the top-level flag parser for
|
||||
|
@ -112,6 +113,16 @@ func (config *Config) InstallCommonFlags(cmd *flag.FlagSet, usageFn func(string)
|
|||
cmd.Var(opts.NewNamedMapOpts("cluster-store-opts", config.ClusterOpts, nil), []string{"-cluster-store-opt"}, usageFn("Set cluster store options"))
|
||||
}
|
||||
|
||||
// IsValueSet returns true if a configuration value
|
||||
// was explicitly set in the configuration file.
|
||||
func (config *Config) IsValueSet(name string) bool {
|
||||
if config.valuesSet == nil {
|
||||
return false
|
||||
}
|
||||
_, ok := config.valuesSet[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
func parseClusterAdvertiseSettings(clusterStore, clusterAdvertise string) (string, error) {
|
||||
if clusterAdvertise == "" {
|
||||
return "", errDiscoveryDisabled
|
||||
|
@ -165,6 +176,7 @@ func getConflictFreeConfiguration(configFile string, flags *flag.FlagSet) (*Conf
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var config Config
|
||||
var reader io.Reader
|
||||
if flags != nil {
|
||||
var jsonConfig map[string]interface{}
|
||||
|
@ -173,22 +185,22 @@ func getConflictFreeConfiguration(configFile string, flags *flag.FlagSet) (*Conf
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := findConfigurationConflicts(jsonConfig, flags); err != nil {
|
||||
configSet := configValuesSet(jsonConfig)
|
||||
|
||||
if err := findConfigurationConflicts(configSet, flags); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config.valuesSet = configSet
|
||||
}
|
||||
|
||||
var config Config
|
||||
reader = bytes.NewReader(b)
|
||||
err = json.NewDecoder(reader).Decode(&config)
|
||||
return &config, err
|
||||
}
|
||||
|
||||
// findConfigurationConflicts iterates over the provided flags searching for
|
||||
// duplicated configurations. It returns an error with all the conflicts if
|
||||
// it finds any.
|
||||
func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagSet) error {
|
||||
var conflicts []string
|
||||
// configValuesSet returns the configuration values explicitly set in the file.
|
||||
func configValuesSet(config map[string]interface{}) map[string]interface{} {
|
||||
flatten := make(map[string]interface{})
|
||||
for k, v := range config {
|
||||
if m, ok := v.(map[string]interface{}); ok {
|
||||
|
@ -199,6 +211,14 @@ func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagS
|
|||
flatten[k] = v
|
||||
}
|
||||
}
|
||||
return flatten
|
||||
}
|
||||
|
||||
// findConfigurationConflicts iterates over the provided flags searching for
|
||||
// duplicated configurations. It returns an error with all the conflicts if
|
||||
// it finds any.
|
||||
func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagSet) error {
|
||||
var conflicts []string
|
||||
|
||||
printConflict := func(name string, flagValue, fileValue interface{}) string {
|
||||
return fmt.Sprintf("%s: (from flag: %v, from file: %v)", name, flagValue, fileValue)
|
||||
|
@ -207,7 +227,7 @@ func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagS
|
|||
collectConflicts := func(f *flag.Flag) {
|
||||
// search option name in the json configuration payload if the value is a named option
|
||||
if namedOption, ok := f.Value.(opts.NamedOption); ok {
|
||||
if optsValue, ok := flatten[namedOption.Name()]; ok {
|
||||
if optsValue, ok := config[namedOption.Name()]; ok {
|
||||
conflicts = append(conflicts, printConflict(namedOption.Name(), f.Value.String(), optsValue))
|
||||
}
|
||||
} else {
|
||||
|
@ -215,7 +235,7 @@ func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagS
|
|||
for _, name := range f.Names {
|
||||
name = strings.TrimLeft(name, "-")
|
||||
|
||||
if value, ok := flatten[name]; ok {
|
||||
if value, ok := config[name]; ok {
|
||||
conflicts = append(conflicts, printConflict(name, f.Value.String(), value))
|
||||
break
|
||||
}
|
||||
|
|
|
@ -55,16 +55,7 @@ func init() {
|
|||
func postParseCommon() {
|
||||
cmd := commonFlags.FlagSet
|
||||
|
||||
if commonFlags.LogLevel != "" {
|
||||
lvl, err := logrus.ParseLevel(commonFlags.LogLevel)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", commonFlags.LogLevel)
|
||||
os.Exit(1)
|
||||
}
|
||||
logrus.SetLevel(lvl)
|
||||
} else {
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
}
|
||||
setDaemonLogLevel(commonFlags.LogLevel)
|
||||
|
||||
// Regardless of whether the user sets it to true or false, if they
|
||||
// specify --tlsverify at all then we need to turn on tls
|
||||
|
@ -93,3 +84,16 @@ func postParseCommon() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setDaemonLogLevel(logLevel string) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -360,5 +360,14 @@ func loadDaemonCliConfig(config *daemon.Config, daemonFlags *flag.FlagSet, commo
|
|||
}
|
||||
}
|
||||
|
||||
// Regardless of whether the user sets it to true or false, if they
|
||||
// specify TLSVerify at all then we need to turn on TLS
|
||||
if config.IsValueSet("tls-verify") {
|
||||
config.TLS = true
|
||||
}
|
||||
|
||||
// ensure that the log level is the one set after merging configurations
|
||||
setDaemonLogLevel(config.LogLevel)
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/cli"
|
||||
"github.com/docker/docker/daemon"
|
||||
"github.com/docker/docker/opts"
|
||||
|
@ -89,3 +90,126 @@ func TestLoadDaemonCliConfigWithConflicts(t *testing.T) {
|
|||
t.Fatalf("expected labels conflict, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) {
|
||||
c := &daemon.Config{}
|
||||
common := &cli.CommonFlags{
|
||||
TLSOptions: &tlsconfig.Options{
|
||||
CAFile: "/tmp/ca.pem",
|
||||
},
|
||||
}
|
||||
|
||||
f, err := ioutil.TempFile("", "docker-config-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
configFile := f.Name()
|
||||
f.Write([]byte(`{"tls-verify": true}`))
|
||||
f.Close()
|
||||
|
||||
flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
|
||||
loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if loadedConfig == nil {
|
||||
t.Fatalf("expected configuration %v, got nil", c)
|
||||
}
|
||||
|
||||
if !loadedConfig.TLS {
|
||||
t.Fatalf("expected TLS enabled, got %q", loadedConfig)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) {
|
||||
c := &daemon.Config{}
|
||||
common := &cli.CommonFlags{
|
||||
TLSOptions: &tlsconfig.Options{
|
||||
CAFile: "/tmp/ca.pem",
|
||||
},
|
||||
}
|
||||
|
||||
f, err := ioutil.TempFile("", "docker-config-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
configFile := f.Name()
|
||||
f.Write([]byte(`{"tls-verify": false}`))
|
||||
f.Close()
|
||||
|
||||
flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
|
||||
loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if loadedConfig == nil {
|
||||
t.Fatalf("expected configuration %v, got nil", c)
|
||||
}
|
||||
|
||||
if !loadedConfig.TLS {
|
||||
t.Fatalf("expected TLS enabled, got %q", loadedConfig)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) {
|
||||
c := &daemon.Config{}
|
||||
common := &cli.CommonFlags{
|
||||
TLSOptions: &tlsconfig.Options{
|
||||
CAFile: "/tmp/ca.pem",
|
||||
},
|
||||
}
|
||||
|
||||
f, err := ioutil.TempFile("", "docker-config-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
configFile := f.Name()
|
||||
f.Write([]byte(`{}`))
|
||||
f.Close()
|
||||
|
||||
flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
|
||||
loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if loadedConfig == nil {
|
||||
t.Fatalf("expected configuration %v, got nil", c)
|
||||
}
|
||||
|
||||
if loadedConfig.TLS {
|
||||
t.Fatalf("expected TLS disabled, got %q", loadedConfig)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) {
|
||||
c := &daemon.Config{}
|
||||
common := &cli.CommonFlags{}
|
||||
|
||||
f, err := ioutil.TempFile("", "docker-config-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
configFile := f.Name()
|
||||
f.Write([]byte(`{"log-level": "warn"}`))
|
||||
f.Close()
|
||||
|
||||
flags := mflag.NewFlagSet("test", mflag.ContinueOnError)
|
||||
loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if loadedConfig == nil {
|
||||
t.Fatalf("expected configuration %v, got nil", c)
|
||||
}
|
||||
if loadedConfig.LogLevel != "warn" {
|
||||
t.Fatalf("expected warn log level, got %v", loadedConfig.LogLevel)
|
||||
}
|
||||
|
||||
if logrus.GetLevel() != logrus.WarnLevel {
|
||||
t.Fatalf("expected warn log level, got %v", logrus.GetLevel())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue