github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/romulus/listwallets/list-wallets.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package listwallets 5 6 import ( 7 "fmt" 8 "io" 9 "sort" 10 11 "github.com/gosuri/uitable" 12 "github.com/juju/cmd" 13 "github.com/juju/errors" 14 "github.com/juju/gnuflag" 15 api "github.com/juju/romulus/api/budget" 16 wireformat "github.com/juju/romulus/wireformat/budget" 17 "gopkg.in/macaroon-bakery.v2-unstable/httpbakery" 18 19 jujucmd "github.com/juju/juju/cmd" 20 rcmd "github.com/juju/juju/cmd/juju/romulus" 21 "github.com/juju/juju/cmd/modelcmd" 22 ) 23 24 // NewListWalletsCommand returns a new command that is used 25 // to list wallets a user has access to. 26 func NewListWalletsCommand() modelcmd.ControllerCommand { 27 return modelcmd.WrapController(&listWalletsCommand{}) 28 } 29 30 type listWalletsCommand struct { 31 modelcmd.ControllerCommandBase 32 33 out cmd.Output 34 } 35 36 const listWalletsDoc = ` 37 List the available wallets. 38 39 Examples: 40 juju wallets 41 ` 42 43 // Info implements cmd.Command.Info. 44 func (c *listWalletsCommand) Info() *cmd.Info { 45 return jujucmd.Info(&cmd.Info{ 46 Name: "wallets", 47 Purpose: "List wallets.", 48 Doc: listWalletsDoc, 49 Aliases: []string{"list-wallets"}, 50 }) 51 } 52 53 // SetFlags implements cmd.Command.SetFlags. 54 func (c *listWalletsCommand) SetFlags(f *gnuflag.FlagSet) { 55 c.CommandBase.SetFlags(f) 56 c.out.AddFlags(f, "tabular", map[string]cmd.Formatter{ 57 "tabular": formatTabular, 58 "json": cmd.FormatJson, 59 }) 60 } 61 62 func (c *listWalletsCommand) Run(ctx *cmd.Context) error { 63 client, err := c.BakeryClient() 64 if err != nil { 65 return errors.Annotate(err, "failed to create an http client") 66 } 67 apiRoot, err := rcmd.GetMeteringURLForControllerCmd(&c.ControllerCommandBase) 68 if err != nil { 69 return errors.Trace(err) 70 } 71 api, err := newAPIClient(apiRoot, client) 72 if err != nil { 73 return errors.Annotate(err, "failed to create an api client") 74 } 75 wallets, err := api.ListWallets() 76 if err != nil { 77 return errors.Annotate(err, "failed to retrieve wallets") 78 } 79 if wallets == nil { 80 return errors.New("no wallet information available") 81 } 82 err = c.out.Write(ctx, wallets) 83 if err != nil { 84 return errors.Trace(err) 85 } 86 return nil 87 } 88 89 // formatTabular returns a tabular view of available wallets. 90 func formatTabular(writer io.Writer, value interface{}) error { 91 b, ok := value.(*wireformat.ListWalletsResponse) 92 if !ok { 93 return errors.Errorf("expected value of type %T, got %T", b, value) 94 } 95 sort.Sort(b.Wallets) 96 97 table := uitable.New() 98 table.MaxColWidth = 50 99 table.Wrap = true 100 for _, col := range []int{1, 2, 3, 4} { 101 table.RightAlign(col) 102 } 103 104 table.AddRow("Wallet", "Monthly", "Budgeted", "Available", "Spent") 105 for _, walletEntry := range b.Wallets { 106 suffix := "" 107 if walletEntry.Default { 108 suffix = "*" 109 } 110 table.AddRow(walletEntry.Wallet+suffix, walletEntry.Limit, walletEntry.Budgeted, walletEntry.Available, walletEntry.Consumed) 111 } 112 table.AddRow("Total", b.Total.Limit, b.Total.Budgeted, b.Total.Available, b.Total.Consumed) 113 table.AddRow("", "", "", "", "") 114 table.AddRow("Credit limit:", b.Credit, "", "", "") 115 fmt.Fprint(writer, table) 116 return nil 117 } 118 119 var newAPIClient = newAPIClientImpl 120 121 func newAPIClientImpl(apiRoot string, c *httpbakery.Client) (apiClient, error) { 122 return api.NewClient(api.APIRoot(apiRoot), api.HTTPClient(c)) 123 } 124 125 type apiClient interface { 126 // ListWallets returns a list of wallets a user has access to. 127 ListWallets() (*wireformat.ListWalletsResponse, error) 128 }