github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/cmd/juju/environment/users.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for infos.
     3  
     4  package environment
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"text/tabwriter"
    10  	"time"
    11  
    12  	"github.com/juju/cmd"
    13  	"github.com/juju/errors"
    14  	"launchpad.net/gnuflag"
    15  
    16  	"github.com/juju/juju/apiserver/params"
    17  	"github.com/juju/juju/cmd/envcmd"
    18  	"github.com/juju/juju/cmd/juju/user"
    19  )
    20  
    21  const ListCommandDoc = `List all users with access to the current environment`
    22  
    23  // UsersCommand shows all the users with access to the current environment.
    24  type UsersCommand struct {
    25  	envcmd.EnvCommandBase
    26  	out cmd.Output
    27  	api UsersAPI
    28  }
    29  
    30  // UserInfo defines the serialization behaviour of the user information.
    31  type UserInfo struct {
    32  	Username       string `yaml:"user-name" json:"user-name"`
    33  	DateCreated    string `yaml:"date-created" json:"date-created"`
    34  	LastConnection string `yaml:"last-connection" json:"last-connection"`
    35  }
    36  
    37  // UsersAPI defines the methods on the client API that the
    38  // users command calls.
    39  type UsersAPI interface {
    40  	Close() error
    41  	EnvironmentUserInfo() ([]params.EnvUserInfo, error)
    42  }
    43  
    44  func (c *UsersCommand) getAPI() (UsersAPI, error) {
    45  	if c.api != nil {
    46  		return c.api, nil
    47  	}
    48  	return c.NewAPIClient()
    49  }
    50  
    51  // Info implements Command.Info.
    52  func (c *UsersCommand) Info() *cmd.Info {
    53  	return &cmd.Info{
    54  		Name:    "users",
    55  		Purpose: "shows all users with access to the current environment",
    56  		Doc:     ListCommandDoc,
    57  	}
    58  }
    59  
    60  // SetFlags implements Command.SetFlags.
    61  func (c *UsersCommand) SetFlags(f *gnuflag.FlagSet) {
    62  	c.out.AddFlags(f, "tabular", map[string]cmd.Formatter{
    63  		"yaml":    cmd.FormatYaml,
    64  		"json":    cmd.FormatJson,
    65  		"tabular": c.formatTabular,
    66  	})
    67  }
    68  
    69  // Run implements Command.Run.
    70  func (c *UsersCommand) Run(ctx *cmd.Context) (err error) {
    71  	client, err := c.getAPI()
    72  	if err != nil {
    73  		return err
    74  	}
    75  	defer client.Close()
    76  
    77  	result, err := client.EnvironmentUserInfo()
    78  	if err != nil {
    79  		return err
    80  	}
    81  
    82  	return c.out.Write(ctx, c.apiUsersToUserInfoSlice(result))
    83  }
    84  
    85  // formatTabular takes an interface{} to adhere to the cmd.Formatter interface
    86  func (c *UsersCommand) formatTabular(value interface{}) ([]byte, error) {
    87  	users, ok := value.([]UserInfo)
    88  	if !ok {
    89  		return nil, errors.Errorf("expected value of type %T, got %T", users, value)
    90  	}
    91  	var out bytes.Buffer
    92  	const (
    93  		// To format things into columns.
    94  		minwidth = 0
    95  		tabwidth = 1
    96  		padding  = 2
    97  		padchar  = ' '
    98  		flags    = 0
    99  	)
   100  	tw := tabwriter.NewWriter(&out, minwidth, tabwidth, padding, padchar, flags)
   101  	fmt.Fprintf(tw, "NAME\tDATE CREATED\tLAST CONNECTION\n")
   102  	for _, user := range users {
   103  		fmt.Fprintf(tw, "%s\t%s\t%s\n", user.Username, user.DateCreated, user.LastConnection)
   104  	}
   105  	tw.Flush()
   106  	return out.Bytes(), nil
   107  }
   108  
   109  func (c *UsersCommand) apiUsersToUserInfoSlice(users []params.EnvUserInfo) []UserInfo {
   110  	var output []UserInfo
   111  	for _, info := range users {
   112  		outInfo := UserInfo{Username: info.UserName}
   113  		outInfo.DateCreated = user.UserFriendlyDuration(info.DateCreated, time.Now())
   114  		if info.LastConnection != nil {
   115  			outInfo.LastConnection = user.UserFriendlyDuration(*info.LastConnection, time.Now())
   116  		} else {
   117  			outInfo.LastConnection = "never connected"
   118  		}
   119  
   120  		output = append(output, outInfo)
   121  	}
   122  
   123  	return output
   124  }