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 }