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 }