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  }