launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/provider/joyent/provider.go (about) 1 // Copyright 2013 Joyent Inc. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package joyent 5 6 import ( 7 "errors" 8 "fmt" 9 10 "github.com/loggo/loggo" 11 12 "launchpad.net/juju-core/environs" 13 "launchpad.net/juju-core/environs/config" 14 ) 15 16 var logger = loggo.GetLogger("juju.provider.joyent") 17 18 type environProvider struct{} 19 20 var providerInstance = environProvider{} 21 var _ environs.EnvironProvider = providerInstance 22 23 func init() { 24 // This will only happen in binaries that actually import this provider 25 // somewhere. To enable a provider, import it in the "providers/all" 26 // package; please do *not* import individual providers anywhere else, 27 // except for tests for that provider. 28 environs.RegisterProvider("joyent", providerInstance) 29 } 30 31 var errNotImplemented = errors.New("not implemented in Joyent provider") 32 33 func (environProvider) Prepare(cfg *config.Config) (environs.Environ, error) { 34 // This method may be called with an incomplete cfg. It should make every 35 // reasonable effort to create a valid configuration based on the supplied, 36 // and open the resulting environment. 37 // You should implement this method to the best of your ability before 38 // expecting non-developers to use your provider, but it shouldn't be your 39 // first priority. 40 preparedCfg, err := prepareConfig(cfg) 41 if err != nil { 42 return nil, err 43 } 44 return providerInstance.Open(preparedCfg) 45 } 46 47 func (environProvider) Open(cfg *config.Config) (environs.Environ, error) { 48 env := &environ{name: cfg.Name()} 49 if err := env.SetConfig(cfg); err != nil { 50 return nil, err 51 } 52 return env, nil 53 } 54 55 func (environProvider) Validate(cfg, old *config.Config) (valid *config.Config, err error) { 56 // You should almost certainly not change this method; if you need to change 57 // how configs are validated, you should edit validateConfig itself, to ensure 58 // that your checks are always applied. 59 newEcfg, err := validateConfig(cfg, nil) 60 if err != nil { 61 return nil, fmt.Errorf("invalid Joyent provider config: %v", err) 62 } 63 if old != nil { 64 oldEcfg, err := validateConfig(old, nil) 65 if err != nil { 66 return nil, fmt.Errorf("original Joyent provider config is invalid: %v", err) 67 } 68 if newEcfg, err = validateConfig(cfg, oldEcfg); err != nil { 69 return nil, fmt.Errorf("invalid Joyent provider config change: %v", err) 70 } 71 } 72 return newEcfg.Config, nil 73 } 74 75 func (environProvider) SecretAttrs(cfg *config.Config) (map[string]string, error) { 76 // If you keep configSecretFields up to date, this method should Just Work. 77 ecfg, err := validateConfig(cfg, nil) 78 if err != nil { 79 return nil, err 80 } 81 secretAttrs := map[string]string{} 82 for _, field := range configSecretFields { 83 if value, ok := ecfg.attrs[field]; ok { 84 if stringValue, ok := value.(string); ok { 85 secretAttrs[field] = stringValue 86 } else { 87 // All your secret attributes must be strings at the moment. Sorry. 88 // It's an expedient and hopefully temporary measure that helps us 89 // plug a security hole in the API. 90 return nil, fmt.Errorf( 91 "secret %q field must have a string value; got %v", 92 field, value, 93 ) 94 } 95 } 96 } 97 return secretAttrs, nil 98 } 99 100 func (environProvider) BoilerplateConfig() string { 101 return boilerplateConfig 102 103 } 104 func (environProvider) PublicAddress() (string, error) { 105 // Don't bother implementing this method until you're ready to deploy units. 106 // You probably won't need to by that stage; it's due for retirement. If it 107 // turns out that you do need to, remember that this method will *only* be 108 // called in code running on an instance in an environment using this 109 // provider; and it needs to return the address of *that* instance. 110 return "", errNotImplemented 111 } 112 113 func (environProvider) PrivateAddress() (string, error) { 114 // Don't bother implementing this method until you're ready to deploy units. 115 // You probably won't need to by that stage; it's due for retirement. If it 116 // turns out that you do need to, remember that this method will *only* be 117 // called in code running on an instance in an environment using this 118 // provider; and it needs to return the address of *that* instance. 119 return "", errNotImplemented 120 }