github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/model/users.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for infos.
     3  
     4  package model
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"text/tabwriter"
    10  	"time"
    11  
    12  	"github.com/juju/cmd"
    13  	"github.com/juju/errors"
    14  	"github.com/juju/utils/set"
    15  	"launchpad.net/gnuflag"
    16  
    17  	"github.com/juju/juju/apiserver/params"
    18  	"github.com/juju/juju/cmd/juju/common"
    19  	"github.com/juju/juju/cmd/modelcmd"
    20  )
    21  
    22  var usageListSharesSummary = `
    23  Shows all users with access to a model for the current controller.`[1:]
    24  
    25  var usageListSharesDetails = `
    26  By default, the model is the current model.
    27  
    28  Examples:
    29      juju list-shares
    30      juju list-shares -m mymodel
    31  
    32  See also: 
    33      grant`[1:]
    34  
    35  func NewUsersCommand() cmd.Command {
    36  	return modelcmd.Wrap(&usersCommand{})
    37  }
    38  
    39  // usersCommand shows all the users with access to the current model.
    40  type usersCommand struct {
    41  	modelcmd.ModelCommandBase
    42  	out cmd.Output
    43  	api UsersAPI
    44  }
    45  
    46  // UsersAPI defines the methods on the client API that the
    47  // users command calls.
    48  type UsersAPI interface {
    49  	Close() error
    50  	ModelUserInfo() ([]params.ModelUserInfo, error)
    51  }
    52  
    53  func (c *usersCommand) getAPI() (UsersAPI, error) {
    54  	if c.api != nil {
    55  		return c.api, nil
    56  	}
    57  	return c.NewAPIClient()
    58  }
    59  
    60  // Info implements Command.Info.
    61  func (c *usersCommand) Info() *cmd.Info {
    62  	return &cmd.Info{
    63  		Name:    "list-shares",
    64  		Purpose: usageListSharesSummary,
    65  		Doc:     usageListSharesDetails,
    66  	}
    67  }
    68  
    69  // SetFlags implements Command.SetFlags.
    70  func (c *usersCommand) SetFlags(f *gnuflag.FlagSet) {
    71  	c.out.AddFlags(f, "tabular", map[string]cmd.Formatter{
    72  		"yaml":    cmd.FormatYaml,
    73  		"json":    cmd.FormatJson,
    74  		"tabular": c.formatTabular,
    75  	})
    76  }
    77  
    78  // Run implements Command.Run.
    79  func (c *usersCommand) Run(ctx *cmd.Context) (err error) {
    80  	client, err := c.getAPI()
    81  	if err != nil {
    82  		return err
    83  	}
    84  	defer client.Close()
    85  
    86  	result, err := client.ModelUserInfo()
    87  	if err != nil {
    88  		return err
    89  	}
    90  	return c.out.Write(ctx, common.ModelUserInfoFromParams(result, time.Now()))
    91  }
    92  
    93  // formatTabular takes an interface{} to adhere to the cmd.Formatter interface
    94  func (c *usersCommand) formatTabular(value interface{}) ([]byte, error) {
    95  	users, ok := value.(map[string]common.ModelUserInfo)
    96  	if !ok {
    97  		return nil, errors.Errorf("expected value of type %T, got %T", users, value)
    98  	}
    99  	var out bytes.Buffer
   100  	if err := formatTabularUserInfo(users, &out); err != nil {
   101  		return nil, errors.Trace(err)
   102  	}
   103  	return out.Bytes(), nil
   104  }
   105  
   106  func formatTabularUserInfo(users map[string]common.ModelUserInfo, out *bytes.Buffer) error {
   107  	const (
   108  		// To format things into columns.
   109  		minwidth = 0
   110  		tabwidth = 1
   111  		padding  = 2
   112  		padchar  = ' '
   113  		flags    = 0
   114  	)
   115  	names := set.NewStrings()
   116  	for name := range users {
   117  		names.Add(name)
   118  	}
   119  	tw := tabwriter.NewWriter(out, minwidth, tabwidth, padding, padchar, flags)
   120  	fmt.Fprintf(tw, "NAME\tACCESS\tLAST CONNECTION\n")
   121  	for _, name := range names.SortedValues() {
   122  		user := users[name]
   123  		displayName := name
   124  		if user.DisplayName != "" {
   125  			displayName = fmt.Sprintf("%s (%s)", name, user.DisplayName)
   126  		}
   127  		fmt.Fprintf(tw, "%s\t%s\t%s\n", displayName, user.Access, user.LastConnection)
   128  	}
   129  	tw.Flush()
   130  	return nil
   131  }