github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/core/application/config.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package application 5 6 import ( 7 "fmt" 8 9 "github.com/juju/collections/set" 10 "github.com/juju/errors" 11 "github.com/juju/schema" 12 "gopkg.in/juju/environschema.v1" 13 ) 14 15 // ConfigAttributes is the config for an applcore/application/config.goication. 16 type ConfigAttributes map[string]interface{} 17 18 // Config encapsulates config for an application. 19 type Config struct { 20 attributes map[string]interface{} 21 schema environschema.Fields 22 defaults schema.Defaults 23 } 24 25 // NewConfig returns a new config instance with the given attributes and 26 // allowing for the extra provider attributes. 27 func NewConfig(attrs map[string]interface{}, schema environschema.Fields, defaults schema.Defaults) (*Config, error) { 28 cfg := &Config{schema: schema, defaults: defaults} 29 if err := cfg.setAttributes(attrs); err != nil { 30 return nil, errors.Trace(err) 31 } 32 return cfg, nil 33 } 34 35 func (c *Config) setAttributes(attrs map[string]interface{}) error { 36 checker, err := c.schemaChecker() 37 if err != nil { 38 return errors.Trace(err) 39 } 40 m := make(map[string]interface{}) 41 for k, v := range attrs { 42 m[k] = v 43 } 44 result, err := checker.Coerce(m, nil) 45 if err != nil { 46 return errors.Trace(err) 47 } 48 c.attributes = result.(map[string]interface{}) 49 return nil 50 } 51 52 // KnownConfigKeys returns the valid application config keys. 53 func KnownConfigKeys(schema environschema.Fields) set.Strings { 54 result := set.NewStrings() 55 for name := range schema { 56 result.Add(name) 57 } 58 return result 59 } 60 61 func (c *Config) schemaChecker() (schema.Checker, error) { 62 schemaFields, schemaDefaults, err := c.schema.ValidationSchema() 63 if err != nil { 64 return nil, errors.Trace(err) 65 } 66 for key, value := range c.defaults { 67 schemaDefaults[key] = value 68 } 69 return schema.StrictFieldMap(schemaFields, schemaDefaults), nil 70 } 71 72 // Validate returns an error if the config is not valid. 73 func (c *Config) Validate() error { 74 return nil 75 } 76 77 // Attributes returns all the config attributes. 78 func (c *Config) Attributes() ConfigAttributes { 79 if c == nil { 80 return nil 81 } 82 result := make(ConfigAttributes) 83 for k, v := range c.attributes { 84 result[k] = v 85 } 86 return result 87 } 88 89 // Get gets the specified attribute. 90 func (c ConfigAttributes) Get(attrName string, defaultValue interface{}) interface{} { 91 if val, ok := c[attrName]; ok { 92 return val 93 } 94 return defaultValue 95 } 96 97 // GetInt gets the specified bool attribute. 98 func (c ConfigAttributes) GetBool(attrName string, defaultValue bool) bool { 99 if val, ok := c[attrName]; ok { 100 return val.(bool) 101 } 102 return defaultValue 103 } 104 105 // GetInt gets the specified int attribute. 106 func (c ConfigAttributes) GetInt(attrName string, defaultValue int) int { 107 if val, ok := c[attrName]; ok { 108 if value, ok := val.(float64); ok { 109 return int(value) 110 } 111 return val.(int) 112 } 113 return defaultValue 114 } 115 116 // GetString gets the specified string attribute. 117 func (c ConfigAttributes) GetString(attrName string, defaultValue string) string { 118 if val, ok := c[attrName]; ok { 119 return val.(string) 120 } 121 return defaultValue 122 } 123 124 // GetStringMap gets the specified map attribute as map[string]string. 125 func (c ConfigAttributes) GetStringMap(attrName string, defaultValue map[string]string) (map[string]string, error) { 126 if valData, ok := c[attrName]; ok { 127 result := make(map[string]string) 128 switch val := valData.(type) { 129 case map[string]string: 130 for k, v := range val { 131 result[k] = v 132 } 133 case map[string]interface{}: 134 for k, v := range val { 135 result[k] = fmt.Sprintf("%v", v) 136 } 137 default: 138 return nil, errors.NotValidf("string map value of type %T", val) 139 } 140 return result, nil 141 } 142 return defaultValue, nil 143 }