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