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  }