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  }