github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/provider/azure/environprovider.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package azure 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/loggo" 9 "launchpad.net/gwacl" 10 11 "github.com/juju/juju/environs" 12 "github.com/juju/juju/environs/config" 13 ) 14 15 // Register the Azure provider with Juju. 16 func init() { 17 environs.RegisterProvider("azure", azureEnvironProvider{}) 18 } 19 20 // Logger for the Azure provider. 21 var logger = loggo.GetLogger("juju.provider.azure") 22 23 type azureEnvironProvider struct{} 24 25 // azureEnvironProvider implements EnvironProvider. 26 var _ environs.EnvironProvider = (*azureEnvironProvider)(nil) 27 28 // Open is specified in the EnvironProvider interface. 29 func (prov azureEnvironProvider) Open(cfg *config.Config) (environs.Environ, error) { 30 logger.Debugf("opening environment %q.", cfg.Name()) 31 // We can't return NewEnviron(cfg) directly here because otherwise, 32 // when err is not nil, we end up with a non-nil returned environ and 33 // this breaks the loop in cmd/jujud/upgrade.go:run() (see 34 // http://golang.org/doc/faq#nil_error for the gory details). 35 environ, err := NewEnviron(cfg) 36 if err != nil { 37 return nil, err 38 } 39 return environ, nil 40 } 41 42 // RestrictedConfigAttributes is specified in the EnvironProvider interface. 43 func (prov azureEnvironProvider) RestrictedConfigAttributes() []string { 44 return []string{"location"} 45 } 46 47 // PrepareForCreateEnvironment is specified in the EnvironProvider interface. 48 func (p azureEnvironProvider) PrepareForCreateEnvironment(cfg *config.Config) (*config.Config, error) { 49 return nil, errors.NotImplementedf("PrepareForCreateEnvironment") 50 } 51 52 // PrepareForBootstrap is specified in the EnvironProvider interface. 53 func (prov azureEnvironProvider) PrepareForBootstrap(ctx environs.BootstrapContext, cfg *config.Config) (environs.Environ, error) { 54 // Set availability-sets-enabled to true 55 // by default, unless the user set a value. 56 if _, ok := cfg.AllAttrs()["availability-sets-enabled"]; !ok { 57 var err error 58 cfg, err = cfg.Apply(map[string]interface{}{"availability-sets-enabled": true}) 59 if err != nil { 60 return nil, err 61 } 62 } 63 env, err := prov.Open(cfg) 64 if err != nil { 65 return nil, err 66 } 67 if ctx.ShouldVerifyCredentials() { 68 if err := verifyCredentials(env.(*azureEnviron)); err != nil { 69 return nil, err 70 } 71 } 72 return env, nil 73 } 74 75 // verifyCredentials issues a cheap, non-modifying request to Azure to 76 // verify the configured credentials. If verification fails, a user-friendly 77 // error will be returned, and the original error will be logged at debug 78 // level. 79 var verifyCredentials = func(e *azureEnviron) error { 80 _, err := e.updateStorageAccountKey(e.getSnapshot()) 81 switch err := errors.Cause(err).(type) { 82 case *gwacl.AzureError: 83 if err.Code == "ForbiddenError" { 84 logger.Debugf("azure request failed: %v", err) 85 return errors.New(`authentication failed 86 87 Please ensure the Azure subscription ID and certificate you have specified 88 are correct. You can obtain your subscription ID from the "Settings" page 89 in the Azure management console, where you can also upload a new certificate 90 if necessary.`) 91 } 92 } 93 return err 94 }