github.com/vmware/govmomi@v0.51.0/cli/session/ls.go (about)

     1  // © Broadcom. All Rights Reserved.
     2  // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package session
     6  
     7  import (
     8  	"context"
     9  	"flag"
    10  	"fmt"
    11  	"io"
    12  	"text/tabwriter"
    13  	"time"
    14  
    15  	"github.com/vmware/govmomi/cli"
    16  	"github.com/vmware/govmomi/cli/flags"
    17  	"github.com/vmware/govmomi/property"
    18  	"github.com/vmware/govmomi/vapi/rest"
    19  	"github.com/vmware/govmomi/vim25/methods"
    20  	"github.com/vmware/govmomi/vim25/mo"
    21  	"github.com/vmware/govmomi/vim25/types"
    22  )
    23  
    24  type ls struct {
    25  	*flags.ClientFlag
    26  	*flags.OutputFlag
    27  
    28  	r bool
    29  	s bool
    30  }
    31  
    32  func init() {
    33  	cli.Register("session.ls", &ls{})
    34  }
    35  
    36  func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) {
    37  	cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
    38  	cmd.ClientFlag.Register(ctx, f)
    39  
    40  	cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
    41  	cmd.OutputFlag.Register(ctx, f)
    42  
    43  	f.BoolVar(&cmd.r, "r", false, "List cached REST session (if any)")
    44  	f.BoolVar(&cmd.s, "S", false, "List current SOAP session")
    45  }
    46  
    47  func (cmd *ls) Description() string {
    48  	return `List active sessions.
    49  
    50  All SOAP sessions are listed by default. The '-S' flag will limit this list to the current session.
    51  
    52  Examples:
    53    govc session.ls
    54    govc session.ls -json | jq -r .currentSession.key`
    55  }
    56  
    57  func (cmd *ls) Process(ctx context.Context) error {
    58  	if err := cmd.ClientFlag.Process(ctx); err != nil {
    59  		return err
    60  	}
    61  	if err := cmd.OutputFlag.Process(ctx); err != nil {
    62  		return err
    63  	}
    64  	return nil
    65  }
    66  
    67  type sessionInfo struct {
    68  	cmd *ls
    69  	now *time.Time
    70  	mo.SessionManager
    71  }
    72  
    73  func (s *sessionInfo) Write(w io.Writer) error {
    74  	tw := tabwriter.NewWriter(w, 4, 0, 2, ' ', 0)
    75  
    76  	fmt.Fprintf(tw, "Key\t")
    77  	fmt.Fprintf(tw, "Name\t")
    78  	fmt.Fprintf(tw, "Created\t")
    79  	fmt.Fprintf(tw, "Idle\t")
    80  	fmt.Fprintf(tw, "Host\t")
    81  	fmt.Fprintf(tw, "Agent\t")
    82  	fmt.Fprintf(tw, "\t")
    83  	fmt.Fprint(tw, "\n")
    84  
    85  	for _, v := range s.SessionList {
    86  		idle := "  ."
    87  		if v.Key != s.CurrentSession.Key && v.IpAddress != "-" {
    88  			since := s.now.Sub(v.LastActiveTime)
    89  			if since > time.Hour {
    90  				idle = "old"
    91  			} else {
    92  				idle = (time.Duration(since.Seconds()) * time.Second).String()
    93  			}
    94  		}
    95  		fmt.Fprintf(tw, "%s\t", v.Key)
    96  		fmt.Fprintf(tw, "%s\t", v.UserName)
    97  		fmt.Fprintf(tw, "%s\t", v.LoginTime.Format("2006-01-02 15:04"))
    98  		fmt.Fprintf(tw, "%s\t", idle)
    99  		fmt.Fprintf(tw, "%s\t", v.IpAddress)
   100  		fmt.Fprintf(tw, "%s\t", v.UserAgent)
   101  		fmt.Fprint(tw, "\n")
   102  	}
   103  
   104  	return tw.Flush()
   105  }
   106  
   107  func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error {
   108  	c, err := cmd.Client()
   109  	if err != nil {
   110  		return err
   111  	}
   112  
   113  	var m mo.SessionManager
   114  	var props []string
   115  	pc := property.DefaultCollector(c)
   116  	if cmd.s {
   117  		props = []string{"currentSession"}
   118  	}
   119  
   120  	err = pc.RetrieveOne(ctx, *c.ServiceContent.SessionManager, props, &m)
   121  	if err != nil {
   122  		return err
   123  	}
   124  
   125  	if cmd.s {
   126  		m.SessionList = []types.UserSession{*m.CurrentSession}
   127  	}
   128  
   129  	now, err := methods.GetCurrentTime(ctx, c)
   130  	if err != nil {
   131  		return err
   132  	}
   133  
   134  	// The REST API doesn't include a way to get the complete list of sessions, only the current session.
   135  	if cmd.r {
   136  		rc := new(rest.Client)
   137  		ok, _ := cmd.Session.Load(ctx, rc, cmd.ConfigureTLS)
   138  		if ok {
   139  			rs, err := rc.Session(ctx)
   140  			if err != nil {
   141  				return err
   142  			}
   143  			m.SessionList = append(m.SessionList, types.UserSession{
   144  				Key:            rc.SessionID(),
   145  				UserName:       rs.User + " (REST)",
   146  				LoginTime:      rs.Created,
   147  				LastActiveTime: rs.LastAccessed,
   148  				IpAddress:      "-",
   149  				UserAgent:      c.UserAgent,
   150  			})
   151  		}
   152  	}
   153  
   154  	return cmd.WriteResult(&sessionInfo{cmd, now, m})
   155  }