github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/provider/maas/environprovider.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  	"net/http"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/loggo"
    11  	"github.com/juju/utils"
    12  	"launchpad.net/gomaasapi"
    13  
    14  	"github.com/juju/juju/environs"
    15  	"github.com/juju/juju/environs/config"
    16  )
    17  
    18  // Logger for the MAAS provider.
    19  var logger = loggo.GetLogger("juju.provider.maas")
    20  
    21  type maasEnvironProvider struct{}
    22  
    23  var _ environs.EnvironProvider = (*maasEnvironProvider)(nil)
    24  
    25  var providerInstance maasEnvironProvider
    26  
    27  func init() {
    28  	environs.RegisterProvider("maas", maasEnvironProvider{})
    29  }
    30  
    31  func (maasEnvironProvider) Open(cfg *config.Config) (environs.Environ, error) {
    32  	logger.Debugf("opening environment %q.", cfg.Name())
    33  	env, err := NewEnviron(cfg)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	return env, nil
    38  }
    39  
    40  var errAgentNameAlreadySet = errors.New(
    41  	"maas-agent-name is already set; this should not be set by hand")
    42  
    43  // RestrictedConfigAttributes is specified in the EnvironProvider interface.
    44  func (p maasEnvironProvider) RestrictedConfigAttributes() []string {
    45  	return []string{"maas-server"}
    46  }
    47  
    48  // PrepareForCreateEnvironment is specified in the EnvironProvider interface.
    49  func (p maasEnvironProvider) PrepareForCreateEnvironment(cfg *config.Config) (*config.Config, error) {
    50  	return nil, errors.NotImplementedf("PrepareForCreateEnvironment")
    51  }
    52  
    53  func (p maasEnvironProvider) PrepareForBootstrap(ctx environs.BootstrapContext, cfg *config.Config) (environs.Environ, error) {
    54  	attrs := cfg.UnknownAttrs()
    55  	oldName, found := attrs["maas-agent-name"]
    56  	if found && oldName != "" {
    57  		return nil, errAgentNameAlreadySet
    58  	}
    59  	uuid, err := utils.NewUUID()
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  	attrs["maas-agent-name"] = uuid.String()
    64  	cfg, err = cfg.Apply(attrs)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  	env, err := p.Open(cfg)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	if ctx.ShouldVerifyCredentials() {
    73  		if err := verifyCredentials(env.(*maasEnviron)); err != nil {
    74  			return nil, err
    75  		}
    76  	}
    77  	return env, nil
    78  }
    79  
    80  func verifyCredentials(env *maasEnviron) error {
    81  	// Verify we can connect to the server and authenticate.
    82  	_, err := env.getMAASClient().GetSubObject("maas").CallGet("get_config", nil)
    83  	if err, ok := err.(gomaasapi.ServerError); ok && err.StatusCode == http.StatusUnauthorized {
    84  		logger.Debugf("authentication failed: %v", err)
    85  		return errors.New(`authentication failed.
    86  
    87  Please ensure the credentials are correct.`)
    88  	}
    89  	return nil
    90  }
    91  
    92  // Boilerplate config YAML.  Don't mess with the indentation or add newlines!
    93  var boilerplateYAML = `
    94  # https://juju.ubuntu.com/docs/config-maas.html
    95  maas:
    96      type: maas
    97  
    98      # maas-server specifies the location of the MAAS server. It must
    99      # specify the base path.
   100      #
   101      maas-server: 'http://192.168.1.1/MAAS/'
   102  
   103      # maas-oauth holds the OAuth credentials from MAAS.
   104      #
   105      maas-oauth: '<add your OAuth credentials from MAAS here>'
   106  
   107      # maas-server bootstrap ssh connection options
   108      #
   109  
   110      # bootstrap-timeout time to wait contacting a state server, in seconds.
   111      bootstrap-timeout: 1800
   112  
   113      # Whether or not to refresh the list of available updates for an
   114      # OS. The default option of true is recommended for use in
   115      # production systems, but disabling this can speed up local
   116      # deployments for development or testing.
   117      #
   118      # enable-os-refresh-update: true
   119  
   120      # Whether or not to perform OS upgrades when machines are
   121      # provisioned. The default option of true is recommended for use
   122      # in production systems, but disabling this can speed up local
   123      # deployments for development or testing.
   124      #
   125      # enable-os-upgrade: true
   126  
   127  
   128  `[1:]
   129  
   130  // BoilerplateConfig is specified in the EnvironProvider interface.
   131  func (maasEnvironProvider) BoilerplateConfig() string {
   132  	return boilerplateYAML
   133  }
   134  
   135  // SecretAttrs is specified in the EnvironProvider interface.
   136  func (prov maasEnvironProvider) SecretAttrs(cfg *config.Config) (map[string]string, error) {
   137  	secretAttrs := make(map[string]string)
   138  	maasCfg, err := prov.newConfig(cfg)
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  	secretAttrs["maas-oauth"] = maasCfg.maasOAuth()
   143  	return secretAttrs, nil
   144  }