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  }