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