github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/romulus/listbudgets/list-budgets.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package listbudgets
     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  	"github.com/juju/juju/cmd/modelcmd"
    16  	"gopkg.in/macaroon-bakery.v1/httpbakery"
    17  
    18  	api "github.com/juju/romulus/api/budget"
    19  	wireformat "github.com/juju/romulus/wireformat/budget"
    20  )
    21  
    22  // NewListBudgetsCommand returns a new command that is used
    23  // to list budgets a user has access to.
    24  func NewListBudgetsCommand() modelcmd.CommandBase {
    25  	return &listBudgetsCommand{}
    26  }
    27  
    28  type listBudgetsCommand struct {
    29  	modelcmd.JujuCommandBase
    30  
    31  	out cmd.Output
    32  }
    33  
    34  const listBudgetsDoc = `
    35  List the available budgets.
    36  
    37  Examples:
    38      juju budgets
    39  `
    40  
    41  // Info implements cmd.Command.Info.
    42  func (c *listBudgetsCommand) Info() *cmd.Info {
    43  	return &cmd.Info{
    44  		Name:    "budgets",
    45  		Purpose: "List budgets.",
    46  		Doc:     listBudgetsDoc,
    47  		Aliases: []string{"list-budgets"},
    48  	}
    49  }
    50  
    51  // SetFlags implements cmd.Command.SetFlags.
    52  func (c *listBudgetsCommand) SetFlags(f *gnuflag.FlagSet) {
    53  	c.JujuCommandBase.SetFlags(f)
    54  	c.out.AddFlags(f, "tabular", map[string]cmd.Formatter{
    55  		"tabular": formatTabular,
    56  		"json":    cmd.FormatJson,
    57  	})
    58  }
    59  
    60  func (c *listBudgetsCommand) Run(ctx *cmd.Context) error {
    61  	client, err := c.BakeryClient()
    62  	if err != nil {
    63  		return errors.Annotate(err, "failed to create an http client")
    64  	}
    65  	api, err := newAPIClient(client)
    66  	if err != nil {
    67  		return errors.Annotate(err, "failed to create an api client")
    68  	}
    69  	budgets, err := api.ListBudgets()
    70  	if err != nil {
    71  		return errors.Annotate(err, "failed to retrieve budgets")
    72  	}
    73  	if budgets == nil {
    74  		return errors.New("no budget information available")
    75  	}
    76  	err = c.out.Write(ctx, budgets)
    77  	if err != nil {
    78  		return errors.Trace(err)
    79  	}
    80  	return nil
    81  }
    82  
    83  // formatTabular returns a tabular view of available budgets.
    84  func formatTabular(writer io.Writer, value interface{}) error {
    85  	b, ok := value.(*wireformat.ListBudgetsResponse)
    86  	if !ok {
    87  		return errors.Errorf("expected value of type %T, got %T", b, value)
    88  	}
    89  	sort.Sort(b.Budgets)
    90  
    91  	table := uitable.New()
    92  	table.MaxColWidth = 50
    93  	table.Wrap = true
    94  	for _, col := range []int{1, 2, 3, 4} {
    95  		table.RightAlign(col)
    96  	}
    97  
    98  	table.AddRow("BUDGET", "MONTHLY", "ALLOCATED", "AVAILABLE", "SPENT")
    99  	for _, budgetEntry := range b.Budgets {
   100  		table.AddRow(budgetEntry.Budget, budgetEntry.Limit, budgetEntry.Allocated, budgetEntry.Available, budgetEntry.Consumed)
   101  	}
   102  	table.AddRow("TOTAL", b.Total.Limit, b.Total.Allocated, b.Total.Available, b.Total.Consumed)
   103  	table.AddRow("", "", "", "", "")
   104  	table.AddRow("Credit limit:", b.Credit, "", "", "")
   105  	fmt.Fprint(writer, table)
   106  	return nil
   107  }
   108  
   109  var newAPIClient = newAPIClientImpl
   110  
   111  func newAPIClientImpl(c *httpbakery.Client) (apiClient, error) {
   112  	client := api.NewClient(c)
   113  	return client, nil
   114  }
   115  
   116  type apiClient interface {
   117  	// ListBudgets returns a list of budgets a user has access to.
   118  	ListBudgets() (*wireformat.ListBudgetsResponse, error)
   119  }