github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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/jsonschema" 13 "github.com/juju/loggo" 14 "github.com/juju/utils" 15 16 "github.com/juju/juju/cloud" 17 "github.com/juju/juju/environs" 18 "github.com/juju/juju/environs/config" 19 "github.com/juju/juju/environs/context" 20 "github.com/juju/juju/environs/simplestreams" 21 ) 22 23 var logger = loggo.GetLogger("juju.provider.cloudsigma") 24 25 const ( 26 providerType = "cloudsigma" 27 ) 28 29 func getImageSource(env environs.Environ) (simplestreams.DataSource, error) { 30 e, ok := env.(*environ) 31 if !ok { 32 return nil, errors.NotSupportedf("non-cloudsigma model") 33 } 34 return simplestreams.NewURLDataSource( 35 "cloud images", 36 fmt.Sprintf(CloudsigmaCloudImagesURLTemplate, e.cloud.Region), 37 utils.VerifySSLHostnames, 38 simplestreams.SPECIFIC_CLOUD_DATA, 39 false, 40 ), nil 41 } 42 43 type environProvider struct { 44 environProviderCredentials 45 } 46 47 var providerInstance = environProvider{} 48 49 // check the provider implements environs.EnvironProvider interface 50 var _ environs.CloudEnvironProvider = (*environProvider)(nil) 51 52 func init() { 53 // This will only happen in binaries that actually import this provider 54 // somewhere. To enable a provider, import it in the "providers/all" 55 // package; please do *not* import individual providers anywhere else, 56 // except in direct tests for that provider. 57 environs.RegisterProvider("cloudsigma", providerInstance) 58 environs.RegisterImageDataSourceFunc("cloud sigma image source", getImageSource) 59 } 60 61 // Version is part of the EnvironProvider interface. 62 func (environProvider) Version() int { 63 return 0 64 } 65 66 // Open opens the environment and returns it. 67 // The configuration must have come from a previously 68 // prepared environment. 69 func (environProvider) Open(args environs.OpenParams) (environs.Environ, error) { 70 logger.Infof("opening model %q", args.Config.Name()) 71 if err := validateCloudSpec(args.Cloud); err != nil { 72 return nil, errors.Annotate(err, "validating cloud spec") 73 } 74 75 client, err := newClient(args.Cloud, args.Config.UUID()) 76 if err != nil { 77 return nil, errors.Trace(err) 78 } 79 env := &environ{ 80 name: args.Config.Name(), 81 cloud: args.Cloud, 82 client: client, 83 } 84 if err := env.SetConfig(args.Config); err != nil { 85 return nil, err 86 } 87 88 return env, nil 89 } 90 91 // CloudSchema returns the schema used to validate input for add-cloud. Since 92 // this provider does not support custom clouds, this always returns nil. 93 func (p environProvider) CloudSchema() *jsonschema.Schema { 94 return nil 95 } 96 97 // Ping tests the connection to the cloud, to verify the endpoint is valid. 98 func (p environProvider) Ping(ctx context.ProviderCallContext, endpoint string) error { 99 return errors.NotImplementedf("Ping") 100 } 101 102 // PrepareConfig is defined by EnvironProvider. 103 func (environProvider) PrepareConfig(args environs.PrepareConfigParams) (*config.Config, error) { 104 if err := validateCloudSpec(args.Cloud); err != nil { 105 return nil, errors.Annotate(err, "validating cloud spec") 106 } 107 return args.Config, nil 108 } 109 110 // Validate ensures that config is a valid configuration for this 111 // provider, applying changes to it if necessary, and returns the 112 // validated configuration. 113 // If old is not nil, it holds the previous environment configuration 114 // for consideration when validating changes. 115 func (environProvider) Validate(cfg, old *config.Config) (*config.Config, error) { 116 logger.Infof("validating model %q", cfg.Name()) 117 118 // You should almost certainly not change this method; if you need to change 119 // how configs are validated, you should edit validateConfig itself, to ensure 120 // that your checks are always applied. 121 newEcfg, err := validateConfig(cfg, nil) 122 if err != nil { 123 return nil, errors.Errorf("invalid config: %v", err) 124 } 125 if old != nil { 126 oldEcfg, err := validateConfig(old, nil) 127 if err != nil { 128 return nil, errors.Errorf("invalid base config: %v", err) 129 } 130 if newEcfg, err = validateConfig(cfg, oldEcfg); err != nil { 131 return nil, errors.Errorf("invalid config change: %v", err) 132 } 133 } 134 135 return newEcfg.Config, nil 136 } 137 138 func validateCloudSpec(spec environs.CloudSpec) error { 139 if err := spec.Validate(); err != nil { 140 return errors.Trace(err) 141 } 142 if spec.Credential == nil { 143 return errors.NotValidf("missing credential") 144 } 145 if authType := spec.Credential.AuthType(); authType != cloud.UserPassAuthType { 146 return errors.NotSupportedf("%q auth-type", authType) 147 } 148 return nil 149 }