github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/environs/config.go (about) 1 // Copyright 2011, 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package environs 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/loggo" 11 ) 12 13 var logger = loggo.GetLogger("juju.environs") 14 15 // ProviderRegistry is an interface that provides methods for registering 16 // and obtaining environment providers by provider name. 17 type ProviderRegistry interface { 18 // RegisterProvider registers a new environment provider with the given 19 // name, and zero or more aliases. If a provider already exists with the 20 // given name or alias, an error will be returned. 21 RegisterProvider(p EnvironProvider, providerType string, providerTypeAliases ...string) error 22 23 // UnregisterProvider unregisters the environment provider with the given name. 24 UnregisterProvider(providerType string) 25 26 // RegisteredProviders returns the names of the registered environment 27 // providers. 28 RegisteredProviders() []string 29 30 // Provider returns the environment provider with the specified name. 31 Provider(providerType string) (EnvironProvider, error) 32 } 33 34 // GlobalProviderRegistry returns the global provider registry. 35 func GlobalProviderRegistry() ProviderRegistry { 36 return globalProviders 37 } 38 39 type globalProviderRegistry struct { 40 // providers maps from provider type to EnvironProvider for 41 // each registered provider type. 42 providers map[string]EnvironProvider 43 // providerAliases is a map of provider type aliases. 44 aliases map[string]string 45 } 46 47 var globalProviders = &globalProviderRegistry{ 48 providers: map[string]EnvironProvider{}, 49 aliases: map[string]string{}, 50 } 51 52 func (r *globalProviderRegistry) RegisterProvider(p EnvironProvider, providerType string, providerTypeAliases ...string) error { 53 if r.providers[providerType] != nil || r.aliases[providerType] != "" { 54 return errors.Errorf("duplicate provider name %q", providerType) 55 } 56 r.providers[providerType] = p 57 for _, alias := range providerTypeAliases { 58 if r.providers[alias] != nil || r.aliases[alias] != "" { 59 return errors.Errorf("duplicate provider alias %q", alias) 60 } 61 r.aliases[alias] = providerType 62 } 63 return nil 64 } 65 66 // UnregisterProvider removes the named provider from the list of available providers. 67 func (r *globalProviderRegistry) UnregisterProvider(providerType string) { 68 delete(r.providers, providerType) 69 for a, p := range r.aliases { 70 if p == providerType { 71 delete(r.aliases, a) 72 } 73 } 74 } 75 76 func (r *globalProviderRegistry) RegisteredProviders() []string { 77 var p []string 78 for k := range r.providers { 79 p = append(p, k) 80 } 81 return p 82 } 83 84 func (r *globalProviderRegistry) Provider(providerType string) (EnvironProvider, error) { 85 if alias, ok := r.aliases[providerType]; ok { 86 providerType = alias 87 } 88 p, ok := r.providers[providerType] 89 if !ok { 90 return nil, errors.NewNotFound( 91 nil, fmt.Sprintf("no registered provider for %q", providerType), 92 ) 93 } 94 return p, nil 95 } 96 97 // RegisterProvider registers a new environment provider. Name gives the name 98 // of the provider, and p the interface to that provider. 99 // 100 // RegisterProvider will panic if the provider name or any of the aliases 101 // are registered more than once. 102 // The return function can be used to unregister the provider and is used by tests. 103 func RegisterProvider(name string, p CloudEnvironProvider, alias ...string) (unregister func()) { 104 if err := GlobalProviderRegistry().RegisterProvider(p, name, alias...); err != nil { 105 panic(fmt.Errorf("juju: %v", err)) 106 } 107 return func() { 108 GlobalProviderRegistry().UnregisterProvider(name) 109 } 110 } 111 112 // RegisteredProviders enumerate all the environ providers which have been registered. 113 func RegisteredProviders() []string { 114 return GlobalProviderRegistry().RegisteredProviders() 115 } 116 117 // Provider returns the previously registered provider with the given type. 118 func Provider(providerType string) (EnvironProvider, error) { 119 return GlobalProviderRegistry().Provider(providerType) 120 }