github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/provider/maas/config.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package maas
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"net/url"
    10  	"strings"
    11  
    12  	"github.com/juju/schema"
    13  	"gopkg.in/juju/environschema.v1"
    14  
    15  	"github.com/juju/juju/environs/config"
    16  )
    17  
    18  var configSchema = environschema.Fields{
    19  	"maas-server": {
    20  		Description: "maas-server specifies the location of the MAAS server. It must specify the base path.",
    21  		Type:        environschema.Tstring,
    22  		Example:     "http://192.168.1.1/MAAS/",
    23  	},
    24  	"maas-oauth": {
    25  		Description: "maas-oauth holds the OAuth credentials from MAAS.",
    26  		Type:        environschema.Tstring,
    27  	},
    28  	"maas-agent-name": {
    29  		Description: "maas-agent-name is an optional UUID to group the instances acquired from MAAS, to support multiple models per MAAS user.",
    30  		Type:        environschema.Tstring,
    31  	},
    32  }
    33  
    34  var configFields = func() schema.Fields {
    35  	fs, _, err := configSchema.ValidationSchema()
    36  	if err != nil {
    37  		panic(err)
    38  	}
    39  	return fs
    40  }()
    41  
    42  var configDefaults = schema.Defaults{
    43  	// For backward-compatibility, maas-agent-name is the empty string
    44  	// by default. However, new environments should all use a UUID.
    45  	"maas-agent-name": "",
    46  }
    47  
    48  type maasModelConfig struct {
    49  	*config.Config
    50  	attrs map[string]interface{}
    51  }
    52  
    53  func (cfg *maasModelConfig) maasServer() string {
    54  	return cfg.attrs["maas-server"].(string)
    55  }
    56  
    57  func (cfg *maasModelConfig) maasOAuth() string {
    58  	return cfg.attrs["maas-oauth"].(string)
    59  }
    60  
    61  func (cfg *maasModelConfig) maasAgentName() string {
    62  	if uuid, ok := cfg.attrs["maas-agent-name"].(string); ok {
    63  		return uuid
    64  	}
    65  	return ""
    66  }
    67  
    68  func (prov maasEnvironProvider) newConfig(cfg *config.Config) (*maasModelConfig, error) {
    69  	validCfg, err := prov.Validate(cfg, nil)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	result := new(maasModelConfig)
    74  	result.Config = validCfg
    75  	result.attrs = validCfg.UnknownAttrs()
    76  	return result, nil
    77  }
    78  
    79  // Schema returns the configuration schema for an environment.
    80  func (maasEnvironProvider) Schema() environschema.Fields {
    81  	fields, err := config.Schema(configSchema)
    82  	if err != nil {
    83  		panic(err)
    84  	}
    85  	return fields
    86  }
    87  
    88  var errMalformedMaasOAuth = errors.New("malformed maas-oauth (3 items separated by colons)")
    89  
    90  func (prov maasEnvironProvider) Validate(cfg, oldCfg *config.Config) (*config.Config, error) {
    91  	// Validate base configuration change before validating MAAS specifics.
    92  	err := config.Validate(cfg, oldCfg)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  
    97  	validated, err := cfg.ValidateUnknownAttrs(configFields, configDefaults)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  
   102  	// Add MAAS specific defaults.
   103  	providerDefaults := make(map[string]interface{})
   104  
   105  	// Storage.
   106  	if _, ok := cfg.StorageDefaultBlockSource(); !ok {
   107  		providerDefaults[config.StorageDefaultBlockSourceKey] = maasStorageProviderType
   108  	}
   109  	if len(providerDefaults) > 0 {
   110  		if cfg, err = cfg.Apply(providerDefaults); err != nil {
   111  			return nil, err
   112  		}
   113  	}
   114  
   115  	if oldCfg != nil {
   116  		oldAttrs := oldCfg.UnknownAttrs()
   117  		validMaasAgentName := false
   118  		if oldName, ok := oldAttrs["maas-agent-name"]; !ok || oldName == nil {
   119  			// If maas-agent-name was nil (because the config was
   120  			// generated pre-1.16.2 the only correct value for it is ""
   121  			// See bug #1256179
   122  			validMaasAgentName = (validated["maas-agent-name"] == "")
   123  		} else {
   124  			validMaasAgentName = (validated["maas-agent-name"] == oldName)
   125  		}
   126  		if !validMaasAgentName {
   127  			return nil, fmt.Errorf("cannot change maas-agent-name")
   128  		}
   129  	}
   130  	envCfg := new(maasModelConfig)
   131  	envCfg.Config = cfg
   132  	envCfg.attrs = validated
   133  	server := envCfg.maasServer()
   134  	serverURL, err := url.Parse(server)
   135  	if err != nil || serverURL.Scheme == "" || serverURL.Host == "" {
   136  		return nil, fmt.Errorf("malformed maas-server URL '%v': %s", server, err)
   137  	}
   138  	oauth := envCfg.maasOAuth()
   139  	if strings.Count(oauth, ":") != 2 {
   140  		return nil, errMalformedMaasOAuth
   141  	}
   142  	return cfg.Apply(envCfg.attrs)
   143  }