func (c *Config) ensureUnitLogging() error { loggingConfig := c.asString("logging-config") // If the logging config hasn't been set, then look for the os environment // variable, and failing that, get the config from loggo itself. if loggingConfig == "" { if environmentValue := os.Getenv(osenv.JujuLoggingConfigEnvKey); environmentValue != "" { loggingConfig = environmentValue } else { loggingConfig = loggo.LoggerInfo() } } levels, err := loggo.ParseConfigurationString(loggingConfig) if err != nil { return err } // If there is is no specified level for "unit", then set one. if _, ok := levels["unit"]; !ok { loggingConfig = loggingConfig + ";unit=DEBUG" } c.defined["logging-config"] = loggingConfig return nil }
// Validate ensures that config is a valid configuration. If old is not nil, // it holds the previous environment configuration for consideration when // validating changes. func Validate(cfg, old *Config) error { // Check that we don't have any disallowed fields. for _, attr := range allowedWithDefaultsOnly { if _, ok := cfg.defined[attr]; ok { return fmt.Errorf("attribute %q is not allowed in configuration", attr) } } // Check that mandatory fields are specified. for _, attr := range mandatoryWithoutDefaults { if _, ok := cfg.defined[attr]; !ok { return fmt.Errorf("%s missing from environment configuration", attr) } } // Check that all other fields that have been specified are non-empty, // unless they're allowed to be empty for backward compatibility, for attr, val := range cfg.defined { if !isEmpty(val) { continue } if !allowEmpty(attr) { return fmt.Errorf("empty %s in environment configuration", attr) } } if strings.ContainsAny(cfg.mustString("name"), "/\\") { return fmt.Errorf("environment name contains unsafe characters") } // Check that the agent version parses ok if set explicitly; otherwise leave // it alone. if v, ok := cfg.defined["agent-version"].(string); ok { if _, err := version.Parse(v); err != nil { return fmt.Errorf("invalid agent version in environment configuration: %q", v) } } // If the logging config is set, make sure it is valid. if v, ok := cfg.defined["logging-config"].(string); ok { if _, err := loggo.ParseConfigurationString(v); err != nil { return err } } // Check firewall mode. if mode := cfg.FirewallMode(); mode != FwInstance && mode != FwGlobal { return fmt.Errorf("invalid firewall mode in environment configuration: %q", mode) } caCert, caCertOK := cfg.CACert() caKey, caKeyOK := cfg.CAPrivateKey() if caCertOK || caKeyOK { if err := verifyKeyPair(caCert, caKey); err != nil { return errors.Annotate(err, "bad CA certificate/key in configuration") } } // Ensure that the auth token is a set of key=value pairs. authToken, _ := cfg.CharmStoreAuth() validAuthToken := regexp.MustCompile(`^([^\s=]+=[^\s=]+(,\s*)?)*$`) if !validAuthToken.MatchString(authToken) { return fmt.Errorf("charm store auth token needs to be a set"+ " of key-value pairs, not %q", authToken) } // Check the immutable config values. These can't change if old != nil { for _, attr := range immutableAttributes { if newv, oldv := cfg.defined[attr], old.defined[attr]; newv != oldv { return fmt.Errorf("cannot change %s from %#v to %#v", attr, oldv, newv) } } if _, oldFound := old.AgentVersion(); oldFound { if _, newFound := cfg.AgentVersion(); !newFound { return fmt.Errorf("cannot clear agent-version") } } } cfg.processDeprecatedAttributes() return nil }