github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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  	// RegisteredProviders returns the names of the registered environment
    24  	// providers.
    25  	RegisteredProviders() []string
    26  
    27  	// Provider returns the environment provider with the specified name.
    28  	Provider(providerType string) (EnvironProvider, error)
    29  }
    30  
    31  // GlobalProviderRegistry returns the global provider registry.
    32  func GlobalProviderRegistry() ProviderRegistry {
    33  	return globalProviders
    34  }
    35  
    36  type globalProviderRegistry struct {
    37  	// providers maps from provider type to EnvironProvider for
    38  	// each registered provider type.
    39  	providers map[string]EnvironProvider
    40  	// providerAliases is a map of provider type aliases.
    41  	aliases map[string]string
    42  }
    43  
    44  var globalProviders = &globalProviderRegistry{
    45  	providers: map[string]EnvironProvider{},
    46  	aliases:   map[string]string{},
    47  }
    48  
    49  func (r *globalProviderRegistry) RegisterProvider(p EnvironProvider, providerType string, providerTypeAliases ...string) error {
    50  	if r.providers[providerType] != nil || r.aliases[providerType] != "" {
    51  		return errors.Errorf("duplicate provider name %q", providerType)
    52  	}
    53  	r.providers[providerType] = p
    54  	for _, alias := range providerTypeAliases {
    55  		if r.providers[alias] != nil || r.aliases[alias] != "" {
    56  			return errors.Errorf("duplicate provider alias %q", alias)
    57  		}
    58  		r.aliases[alias] = providerType
    59  	}
    60  	return nil
    61  }
    62  
    63  func (r *globalProviderRegistry) RegisteredProviders() []string {
    64  	var p []string
    65  	for k := range r.providers {
    66  		p = append(p, k)
    67  	}
    68  	return p
    69  }
    70  
    71  func (r *globalProviderRegistry) Provider(providerType string) (EnvironProvider, error) {
    72  	if alias, ok := r.aliases[providerType]; ok {
    73  		providerType = alias
    74  	}
    75  	p, ok := r.providers[providerType]
    76  	if !ok {
    77  		return nil, errors.NewNotFound(
    78  			nil, fmt.Sprintf("no registered provider for %q", providerType),
    79  		)
    80  	}
    81  	return p, nil
    82  }
    83  
    84  // RegisterProvider registers a new environment provider. Name gives the name
    85  // of the provider, and p the interface to that provider.
    86  //
    87  // RegisterProvider will panic if the provider name or any of the aliases
    88  // are registered more than once.
    89  func RegisterProvider(name string, p EnvironProvider, alias ...string) {
    90  	if err := GlobalProviderRegistry().RegisterProvider(p, name, alias...); err != nil {
    91  		panic(fmt.Errorf("juju: %v", err))
    92  	}
    93  }
    94  
    95  // RegisteredProviders enumerate all the environ providers which have been registered.
    96  func RegisteredProviders() []string {
    97  	return GlobalProviderRegistry().RegisteredProviders()
    98  }
    99  
   100  // Provider returns the previously registered provider with the given type.
   101  func Provider(providerType string) (EnvironProvider, error) {
   102  	return GlobalProviderRegistry().Provider(providerType)
   103  }