github.com/vmware/govmomi@v0.43.0/govc/session/ls.go (about)

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