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 }