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 }