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 }