github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/storage/poolmanager/poolmanager.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package poolmanager
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  
     9  	"github.com/juju/juju/storage"
    10  	"github.com/juju/juju/storage/provider"
    11  )
    12  
    13  const (
    14  	// Pool configuration attribute names.
    15  	Name = "name"
    16  	Type = "type"
    17  )
    18  
    19  var (
    20  	MissingTypeError = errors.New("provider type is missing")
    21  	MissingNameError = errors.New("pool name is missing")
    22  )
    23  
    24  // New returns a PoolManager implementation using the specified state.
    25  func New(settings SettingsManager, registry storage.ProviderRegistry) PoolManager {
    26  	return &poolManager{settings, registry}
    27  }
    28  
    29  var _ PoolManager = (*poolManager)(nil)
    30  
    31  type poolManager struct {
    32  	settings SettingsManager
    33  	registry storage.ProviderRegistry
    34  }
    35  
    36  const globalKeyPrefix = "pool#"
    37  
    38  func globalKey(name string) string {
    39  	return globalKeyPrefix + name
    40  }
    41  
    42  // Create is defined on PoolManager interface.
    43  func (pm *poolManager) Create(name string, providerType storage.ProviderType, attrs map[string]interface{}) (*storage.Config, error) {
    44  	if name == "" {
    45  		return nil, MissingNameError
    46  	}
    47  	if providerType == "" {
    48  		return nil, MissingTypeError
    49  	}
    50  
    51  	cfg, err := storage.NewConfig(name, providerType, attrs)
    52  	if err != nil {
    53  		return nil, errors.Trace(err)
    54  	}
    55  	p, err := pm.registry.StorageProvider(providerType)
    56  	if err != nil {
    57  		return nil, errors.Trace(err)
    58  	}
    59  	if err := provider.ValidateConfig(p, cfg); err != nil {
    60  		return nil, errors.Annotate(err, "validating storage provider config")
    61  	}
    62  
    63  	poolAttrs := cfg.Attrs()
    64  	poolAttrs[Name] = name
    65  	poolAttrs[Type] = string(providerType)
    66  	if err := pm.settings.CreateSettings(globalKey(name), poolAttrs); err != nil {
    67  		return nil, errors.Annotatef(err, "creating pool %q", name)
    68  	}
    69  	return cfg, nil
    70  }
    71  
    72  // Delete is defined on PoolManager interface.
    73  func (pm *poolManager) Delete(name string) error {
    74  	err := pm.settings.RemoveSettings(globalKey(name))
    75  	if err == nil || errors.IsNotFound(err) {
    76  		return nil
    77  	}
    78  	return errors.Annotatef(err, "deleting pool %q", name)
    79  }
    80  
    81  // Get is defined on PoolManager interface.
    82  func (pm *poolManager) Get(name string) (*storage.Config, error) {
    83  	settings, err := pm.settings.ReadSettings(globalKey(name))
    84  	if err != nil {
    85  		if errors.IsNotFound(err) {
    86  			return nil, errors.NotFoundf("pool %q", name)
    87  		} else {
    88  			return nil, errors.Annotatef(err, "reading pool %q", name)
    89  		}
    90  	}
    91  	return pm.configFromSettings(settings)
    92  }
    93  
    94  // List is defined on PoolManager interface.
    95  func (pm *poolManager) List() ([]*storage.Config, error) {
    96  	settings, err := pm.settings.ListSettings(globalKeyPrefix)
    97  	if err != nil {
    98  		return nil, errors.Annotate(err, "listing pool settings")
    99  	}
   100  	var result []*storage.Config
   101  	for _, attrs := range settings {
   102  		cfg, err := pm.configFromSettings(attrs)
   103  		if err != nil {
   104  			return nil, errors.Trace(err)
   105  		}
   106  		result = append(result, cfg)
   107  	}
   108  	return result, nil
   109  }
   110  
   111  func (pm *poolManager) configFromSettings(settings map[string]interface{}) (*storage.Config, error) {
   112  	providerType := storage.ProviderType(settings[Type].(string))
   113  	name := settings[Name].(string)
   114  	// Ensure returned attributes are stripped of name and type,
   115  	// as these are not user-specified attributes.
   116  	delete(settings, Name)
   117  	delete(settings, Type)
   118  	cfg, err := storage.NewConfig(name, providerType, settings)
   119  	if err != nil {
   120  		return nil, errors.Trace(err)
   121  	}
   122  	p, err := pm.registry.StorageProvider(providerType)
   123  	if err != nil {
   124  		return nil, errors.Trace(err)
   125  	}
   126  	if err := provider.ValidateConfig(p, cfg); err != nil {
   127  		return nil, errors.Trace(err)
   128  	}
   129  	return cfg, nil
   130  }