github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/provider/cloudsigma/provider.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // Juju provider for CloudSigma
     5  
     6  package cloudsigma
     7  
     8  import (
     9  	"fmt"
    10  
    11  	"github.com/juju/errors"
    12  	"github.com/juju/loggo"
    13  	"github.com/juju/utils"
    14  
    15  	"github.com/juju/juju/cloud"
    16  	"github.com/juju/juju/environs"
    17  	"github.com/juju/juju/environs/config"
    18  	"github.com/juju/juju/environs/simplestreams"
    19  )
    20  
    21  var logger = loggo.GetLogger("juju.provider.cloudsigma")
    22  
    23  const (
    24  	providerType = "cloudsigma"
    25  )
    26  
    27  func getImageSource(env environs.Environ) (simplestreams.DataSource, error) {
    28  	e, ok := env.(*environ)
    29  	if !ok {
    30  		return nil, errors.NotSupportedf("non-cloudsigma model")
    31  	}
    32  	return simplestreams.NewURLDataSource(
    33  		"cloud images",
    34  		fmt.Sprintf(CloudsigmaCloudImagesURLTemplate, e.cloud.Region),
    35  		utils.VerifySSLHostnames,
    36  		simplestreams.SPECIFIC_CLOUD_DATA,
    37  		false,
    38  	), nil
    39  }
    40  
    41  type environProvider struct {
    42  	environProviderCredentials
    43  }
    44  
    45  var providerInstance = environProvider{}
    46  
    47  // check the provider implements environs.EnvironProvider interface
    48  var _ environs.EnvironProvider = (*environProvider)(nil)
    49  
    50  func init() {
    51  	// This will only happen in binaries that actually import this provider
    52  	// somewhere. To enable a provider, import it in the "providers/all"
    53  	// package; please do *not* import individual providers anywhere else,
    54  	// except in direct tests for that provider.
    55  	environs.RegisterProvider("cloudsigma", providerInstance)
    56  	environs.RegisterImageDataSourceFunc("cloud sigma image source", getImageSource)
    57  }
    58  
    59  // Open opens the environment and returns it.
    60  // The configuration must have come from a previously
    61  // prepared environment.
    62  func (environProvider) Open(args environs.OpenParams) (environs.Environ, error) {
    63  	logger.Infof("opening model %q", args.Config.Name())
    64  	if err := validateCloudSpec(args.Cloud); err != nil {
    65  		return nil, errors.Annotate(err, "validating cloud spec")
    66  	}
    67  
    68  	client, err := newClient(args.Cloud, args.Config.UUID())
    69  	if err != nil {
    70  		return nil, errors.Trace(err)
    71  	}
    72  	env := &environ{
    73  		name:   args.Config.Name(),
    74  		cloud:  args.Cloud,
    75  		client: client,
    76  	}
    77  	if err := env.SetConfig(args.Config); err != nil {
    78  		return nil, err
    79  	}
    80  
    81  	return env, nil
    82  }
    83  
    84  // PrepareConfig is defined by EnvironProvider.
    85  func (environProvider) PrepareConfig(args environs.PrepareConfigParams) (*config.Config, error) {
    86  	if err := validateCloudSpec(args.Cloud); err != nil {
    87  		return nil, errors.Annotate(err, "validating cloud spec")
    88  	}
    89  	return args.Config, nil
    90  }
    91  
    92  // Validate ensures that config is a valid configuration for this
    93  // provider, applying changes to it if necessary, and returns the
    94  // validated configuration.
    95  // If old is not nil, it holds the previous environment configuration
    96  // for consideration when validating changes.
    97  func (environProvider) Validate(cfg, old *config.Config) (*config.Config, error) {
    98  	logger.Infof("validating model %q", cfg.Name())
    99  
   100  	// You should almost certainly not change this method; if you need to change
   101  	// how configs are validated, you should edit validateConfig itself, to ensure
   102  	// that your checks are always applied.
   103  	newEcfg, err := validateConfig(cfg, nil)
   104  	if err != nil {
   105  		return nil, errors.Errorf("invalid config: %v", err)
   106  	}
   107  	if old != nil {
   108  		oldEcfg, err := validateConfig(old, nil)
   109  		if err != nil {
   110  			return nil, errors.Errorf("invalid base config: %v", err)
   111  		}
   112  		if newEcfg, err = validateConfig(cfg, oldEcfg); err != nil {
   113  			return nil, errors.Errorf("invalid config change: %v", err)
   114  		}
   115  	}
   116  
   117  	return newEcfg.Config, nil
   118  }
   119  
   120  func validateCloudSpec(spec environs.CloudSpec) error {
   121  	if err := spec.Validate(); err != nil {
   122  		return errors.Trace(err)
   123  	}
   124  	if spec.Credential == nil {
   125  		return errors.NotValidf("missing credential")
   126  	}
   127  	if authType := spec.Credential.AuthType(); authType != cloud.UserPassAuthType {
   128  		return errors.NotSupportedf("%q auth-type", authType)
   129  	}
   130  	return nil
   131  }