github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/storage/list.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  	"github.com/juju/cmd"
     8  	"github.com/juju/errors"
     9  	"launchpad.net/gnuflag"
    10  
    11  	"github.com/juju/juju/apiserver/params"
    12  	"github.com/juju/juju/cmd/modelcmd"
    13  )
    14  
    15  // NewListCommand returns a command for listing storage instances.
    16  func NewListCommand() cmd.Command {
    17  	cmd := &listCommand{}
    18  	cmd.newAPIFunc = func() (StorageListAPI, error) {
    19  		return cmd.NewStorageAPI()
    20  	}
    21  	return modelcmd.Wrap(cmd)
    22  }
    23  
    24  const listCommandDoc = `
    25  List information about storage instances.
    26  
    27  options:
    28  -m, --model (= "")
    29     juju model to operate in
    30  -o, --output (= "")
    31     specify an output file
    32  --format (= tabular)
    33     specify output format (json|tabular|yaml)
    34  `
    35  
    36  // listCommand returns storage instances.
    37  type listCommand struct {
    38  	StorageCommandBase
    39  	out        cmd.Output
    40  	ids        []string
    41  	filesystem bool
    42  	volume     bool
    43  	newAPIFunc func() (StorageListAPI, error)
    44  }
    45  
    46  // Init implements Command.Init.
    47  func (c *listCommand) Init(args []string) (err error) {
    48  	c.ids = args
    49  	return nil
    50  }
    51  
    52  // Info implements Command.Info.
    53  func (c *listCommand) Info() *cmd.Info {
    54  	return &cmd.Info{
    55  		Name:    "list-storage",
    56  		Args:    "<machineID> ...",
    57  		Purpose: "lists storage details",
    58  		Doc:     listCommandDoc,
    59  		Aliases: []string{"storage"},
    60  	}
    61  }
    62  
    63  // SetFlags implements Command.SetFlags.
    64  func (c *listCommand) SetFlags(f *gnuflag.FlagSet) {
    65  	c.StorageCommandBase.SetFlags(f)
    66  	c.out.AddFlags(f, "tabular", map[string]cmd.Formatter{
    67  		"yaml":    cmd.FormatYaml,
    68  		"json":    cmd.FormatJson,
    69  		"tabular": formatListTabular,
    70  	})
    71  	f.BoolVar(&c.filesystem, "filesystem", false, "list filesystem storage")
    72  	f.BoolVar(&c.volume, "volume", false, "list volume storage")
    73  }
    74  
    75  // Run implements Command.Run.
    76  func (c *listCommand) Run(ctx *cmd.Context) (err error) {
    77  	api, err := c.newAPIFunc()
    78  	if err != nil {
    79  		return err
    80  	}
    81  	defer api.Close()
    82  
    83  	var output interface{}
    84  	if c.filesystem {
    85  		output, err = c.generateListFilesystemsOutput(ctx, api)
    86  	} else if c.volume {
    87  		output, err = c.generateListVolumeOutput(ctx, api)
    88  	} else {
    89  		output, err = c.generateListOutput(ctx, api)
    90  	}
    91  	if err != nil {
    92  		return err
    93  	}
    94  	if output == nil {
    95  		return nil
    96  	}
    97  	return c.out.Write(ctx, output)
    98  }
    99  
   100  // StorageAPI defines the API methods that the storage commands use.
   101  type StorageListAPI interface {
   102  	Close() error
   103  	ListStorageDetails() ([]params.StorageDetails, error)
   104  	ListFilesystems(machines []string) ([]params.FilesystemDetailsListResult, error)
   105  	ListVolumes(machines []string) ([]params.VolumeDetailsListResult, error)
   106  }
   107  
   108  // generateListOutput returns a map of storage details
   109  func (c *listCommand) generateListOutput(ctx *cmd.Context, api StorageListAPI) (output interface{}, err error) {
   110  
   111  	results, err := api.ListStorageDetails()
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  	if len(results) == 0 {
   116  		return nil, nil
   117  	}
   118  	details, err := formatStorageDetails(results)
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  	switch c.out.Name() {
   123  	case "yaml", "json":
   124  		output = map[string]map[string]StorageInfo{"storage": details}
   125  	default:
   126  		output = details
   127  	}
   128  	return output, nil
   129  }
   130  
   131  func formatListTabular(value interface{}) ([]byte, error) {
   132  
   133  	switch value.(type) {
   134  	case map[string]StorageInfo:
   135  		output, err := formatStorageListTabular(value)
   136  		return output, err
   137  
   138  	case map[string]FilesystemInfo:
   139  		output, err := formatFilesystemListTabular(value)
   140  		return output, err
   141  
   142  	case map[string]VolumeInfo:
   143  		output, err := formatVolumeListTabular(value)
   144  		return output, err
   145  
   146  	default:
   147  		return nil, errors.Errorf("unexpected value of type %T", value)
   148  	}
   149  }