github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/block/list.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package block
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"text/tabwriter"
    10  
    11  	"github.com/juju/cmd"
    12  	"github.com/juju/errors"
    13  	"launchpad.net/gnuflag"
    14  
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/cmd/modelcmd"
    17  )
    18  
    19  func newListCommand() cmd.Command {
    20  	return modelcmd.Wrap(&listCommand{})
    21  }
    22  
    23  const listCommandDoc = `
    24  List blocks for Juju model.
    25  This command shows if each block type is enabled. 
    26  For enabled blocks, block message is shown if it was specified.
    27  `
    28  
    29  // listCommand list blocks.
    30  type listCommand struct {
    31  	modelcmd.ModelCommandBase
    32  	out cmd.Output
    33  }
    34  
    35  // Init implements Command.Init.
    36  func (c *listCommand) Init(args []string) (err error) {
    37  	return nil
    38  }
    39  
    40  // Info implements Command.Info.
    41  func (c *listCommand) Info() *cmd.Info {
    42  	return &cmd.Info{
    43  		Name:    "list",
    44  		Purpose: "list juju blocks",
    45  		Doc:     listCommandDoc,
    46  	}
    47  }
    48  
    49  // SetFlags implements Command.SetFlags.
    50  func (c *listCommand) SetFlags(f *gnuflag.FlagSet) {
    51  	c.ModelCommandBase.SetFlags(f)
    52  	c.out.AddFlags(f, "blocks", map[string]cmd.Formatter{
    53  		"yaml":   cmd.FormatYaml,
    54  		"json":   cmd.FormatJson,
    55  		"blocks": formatBlocks,
    56  	})
    57  }
    58  
    59  // Run implements Command.Run.
    60  func (c *listCommand) Run(ctx *cmd.Context) (err error) {
    61  	api, err := getBlockListAPI(&c.ModelCommandBase)
    62  	if err != nil {
    63  		return err
    64  	}
    65  	defer api.Close()
    66  
    67  	result, err := api.List()
    68  	if err != nil {
    69  		return err
    70  	}
    71  	return c.out.Write(ctx, formatBlockInfo(result))
    72  }
    73  
    74  // BlockListAPI defines the client API methods that block list command uses.
    75  type BlockListAPI interface {
    76  	Close() error
    77  	List() ([]params.Block, error)
    78  }
    79  
    80  var getBlockListAPI = func(cmd *modelcmd.ModelCommandBase) (BlockListAPI, error) {
    81  	return getBlockAPI(cmd)
    82  }
    83  
    84  // BlockInfo defines the serialization behaviour of the block information.
    85  type BlockInfo struct {
    86  	Operation string  `yaml:"block" json:"block"`
    87  	Enabled   bool    `yaml:"enabled" json:"enabled"`
    88  	Message   *string `yaml:"message,omitempty" json:"message,omitempty"`
    89  }
    90  
    91  // formatBlockInfo takes a set of Block and creates a
    92  // mapping to information structures.
    93  func formatBlockInfo(all []params.Block) []BlockInfo {
    94  	output := make([]BlockInfo, len(blockArgs))
    95  
    96  	info := make(map[string]BlockInfo, len(all))
    97  	// not all block types may be returned from client
    98  	for _, one := range all {
    99  		op := OperationFromType(one.Type)
   100  		bi := BlockInfo{
   101  			Operation: op,
   102  			// If client returned it, it means that it is enabled
   103  			Enabled: true,
   104  			Message: &one.Message,
   105  		}
   106  		info[op] = bi
   107  	}
   108  
   109  	for i, aType := range blockArgs {
   110  		if val, ok := info[aType]; ok {
   111  			output[i] = val
   112  			continue
   113  		}
   114  		output[i] = BlockInfo{Operation: aType}
   115  	}
   116  
   117  	return output
   118  }
   119  
   120  // formatBlocks returns block list representation.
   121  func formatBlocks(value interface{}) ([]byte, error) {
   122  	blocks, ok := value.([]BlockInfo)
   123  	if !ok {
   124  		return nil, errors.Errorf("expected value of type %T, got %T", blocks, value)
   125  	}
   126  	var out bytes.Buffer
   127  	// To format things as desired.
   128  	tw := tabwriter.NewWriter(&out, 0, 1, 1, ' ', 0)
   129  
   130  	for _, ablock := range blocks {
   131  		fmt.Fprintln(tw)
   132  		switched := "off"
   133  		if ablock.Enabled {
   134  			switched = "on"
   135  		}
   136  		fmt.Fprintf(tw, "%v\t", ablock.Operation)
   137  		if ablock.Message != nil {
   138  			fmt.Fprintf(tw, "\t=%v, %v", switched, *ablock.Message)
   139  			continue
   140  		}
   141  		fmt.Fprintf(tw, "\t=%v", switched)
   142  	}
   143  
   144  	tw.Flush()
   145  
   146  	return out.Bytes(), nil
   147  }