github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/storage/poolcreate.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package storage
     5  
     6  import (
     7  	"strings"
     8  
     9  	"github.com/juju/cmd"
    10  	"github.com/juju/errors"
    11  	"github.com/juju/utils/keyvalues"
    12  
    13  	jujucmd "github.com/juju/juju/cmd"
    14  	"github.com/juju/juju/cmd/modelcmd"
    15  )
    16  
    17  // PoolCreateAPI defines the API methods that pool create command uses.
    18  type PoolCreateAPI interface {
    19  	Close() error
    20  	CreatePool(pname, ptype string, pconfig map[string]interface{}) error
    21  }
    22  
    23  const poolCreateCommandDoc = `
    24  Pools are a mechanism for administrators to define sources of storage that
    25  they will use to satisfy application storage requirements.
    26  
    27  A single pool might be used for storage from units of many different applications -
    28  it is a resource from which different stores may be drawn.
    29  
    30  A pool describes provider-specific parameters for creating storage,
    31  such as performance (e.g. IOPS), media type (e.g. magnetic vs. SSD),
    32  or durability.
    33  
    34  For many providers, there will be a shared resource
    35  where storage can be requested (e.g. EBS in amazon).
    36  Creating pools there maps provider specific settings
    37  into named resources that can be used during deployment.
    38  
    39  Pools defined at the model level are easily reused across applications.
    40  Pool creation requires a pool name, the provider type and attributes for
    41  configuration as space-separated pairs, e.g. tags, size, path, etc.
    42  
    43  Examples:
    44  
    45      juju create-storage-pool ebsrotary ebs volume-type=standard
    46  
    47  See also:
    48      remove-storage-pool
    49      update-storage-pool
    50      storage-pools
    51  `
    52  
    53  // NewPoolCreateCommand returns a command that creates or defines a storage pool
    54  func NewPoolCreateCommand() cmd.Command {
    55  	cmd := &poolCreateCommand{}
    56  	cmd.newAPIFunc = func() (PoolCreateAPI, error) {
    57  		return cmd.NewStorageAPI()
    58  	}
    59  	return modelcmd.Wrap(cmd)
    60  }
    61  
    62  // poolCreateCommand lists storage pools.
    63  type poolCreateCommand struct {
    64  	PoolCommandBase
    65  	newAPIFunc func() (PoolCreateAPI, error)
    66  	poolName   string
    67  	// TODO(anastasiamac 2015-01-29) type will need to become optional
    68  	// if type is unspecified, use the environment's default provider type
    69  	provider string
    70  	attrs    map[string]interface{}
    71  }
    72  
    73  // Init implements Command.Init.
    74  func (c *poolCreateCommand) Init(args []string) (err error) {
    75  	if len(args) < 2 {
    76  		return errors.New("pool creation requires names, provider type and optional attributes for configuration")
    77  	}
    78  
    79  	c.poolName = args[0]
    80  	c.provider = args[1]
    81  
    82  	// poolName and provider can contain any character, except for '='.
    83  	// However, the last arguments are always expected to be key=value pairs.
    84  	// Since it's possible for users to mistype, we want to check here for cases
    85  	// such as:
    86  	//    $ juju create-storage-pool poolName key=value
    87  	//    $ juju create-storage-pool key=value poolName
    88  	// as either a provider or a pool name are missing.
    89  
    90  	if strings.Contains(c.poolName, "=") || strings.Contains(c.provider, "=") {
    91  		return errors.New("pool creation requires names and provider type before optional attributes for configuration")
    92  	}
    93  
    94  	options, err := keyvalues.Parse(args[2:], false)
    95  	if err != nil {
    96  		return err
    97  	}
    98  
    99  	c.attrs = make(map[string]interface{})
   100  	if len(options) == 0 {
   101  		return nil
   102  	}
   103  	for key, value := range options {
   104  		c.attrs[key] = value
   105  	}
   106  	return nil
   107  }
   108  
   109  // Info implements Command.Info.
   110  func (c *poolCreateCommand) Info() *cmd.Info {
   111  	return jujucmd.Info(&cmd.Info{
   112  		Name:    "create-storage-pool",
   113  		Args:    "<name> <provider> [<key>=<value> [<key>=<value>...]]",
   114  		Purpose: "Create or define a storage pool.",
   115  		Doc:     poolCreateCommandDoc,
   116  	})
   117  }
   118  
   119  // Run implements Command.Run.
   120  func (c *poolCreateCommand) Run(ctx *cmd.Context) (err error) {
   121  	api, err := c.newAPIFunc()
   122  	if err != nil {
   123  		return err
   124  	}
   125  	defer api.Close()
   126  	return api.CreatePool(c.poolName, c.provider, c.attrs)
   127  }