github.com/vmware/govmomi@v0.51.0/cli/volume/snapshot/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 snapshot
     6  
     7  import (
     8  	"context"
     9  	"errors"
    10  	"flag"
    11  	"fmt"
    12  	"io"
    13  	"text/tabwriter"
    14  	"time"
    15  
    16  	"github.com/vmware/govmomi/cli"
    17  	"github.com/vmware/govmomi/cli/flags"
    18  	"github.com/vmware/govmomi/cns"
    19  	"github.com/vmware/govmomi/cns/types"
    20  )
    21  
    22  type ls struct {
    23  	*flags.ClientFlag
    24  	*flags.OutputFlag
    25  
    26  	long bool
    27  	id   bool
    28  }
    29  
    30  func init() {
    31  	cli.Register("volume.snapshot.ls", &ls{})
    32  }
    33  
    34  func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) {
    35  	cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
    36  	cmd.ClientFlag.Register(ctx, f)
    37  
    38  	cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
    39  	cmd.OutputFlag.Register(ctx, f)
    40  
    41  	f.BoolVar(&cmd.long, "l", false, "Long listing format")
    42  	f.BoolVar(&cmd.id, "i", false, "List snapshot ID and volume ID only")
    43  }
    44  
    45  func (cmd *ls) Process(ctx context.Context) error {
    46  	if err := cmd.ClientFlag.Process(ctx); err != nil {
    47  		return err
    48  	}
    49  	return cmd.OutputFlag.Process(ctx)
    50  }
    51  
    52  func (cmd *ls) Usage() string {
    53  	return "[ID]..."
    54  }
    55  
    56  func (cmd *ls) Description() string {
    57  	return `List all snapshots of volume ID.
    58  
    59  Use a list of volume IDs to list all snapshots of multiple volumes at once.
    60  
    61  Examples:
    62    govc volume.snapshot.ls df86393b-5ae0-4fca-87d0-b692dbc67d45
    63    govc volume.snapshot.ls -i df86393b-5ae0-4fca-87d0-b692dbc67d45
    64    govc volume.snapshot.ls -l df86393b-5ae0-4fca-87d0-b692dbc67d45
    65    govc volume.snapshot.ls -l $(govc volume.ls -i)`
    66  }
    67  
    68  type lsResult struct {
    69  	Entries []*types.CnsSnapshotQueryResultEntry `json:"entries"`
    70  	cmd     *ls
    71  }
    72  
    73  func (r *lsResult) Write(w io.Writer) error {
    74  	tw := tabwriter.NewWriter(r.cmd.Out, 2, 0, 2, ' ', 0)
    75  	if r.cmd.id {
    76  		for _, e := range r.Entries {
    77  			fmt.Fprintf(tw, "%s\t%s", e.Snapshot.SnapshotId.Id, e.Snapshot.VolumeId.Id)
    78  			fmt.Fprintln(tw)
    79  		}
    80  		return tw.Flush()
    81  	}
    82  
    83  	for _, e := range r.Entries {
    84  		fmt.Fprintf(tw, "%s\t%s", e.Snapshot.SnapshotId.Id, e.Snapshot.Description)
    85  		if r.cmd.long {
    86  			fmt.Fprintf(tw, "\t%s\t%s", e.Snapshot.VolumeId.Id, e.Snapshot.CreateTime.Format(time.Stamp))
    87  		}
    88  		fmt.Fprintln(tw)
    89  	}
    90  	return tw.Flush()
    91  }
    92  
    93  func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error {
    94  	if len(f.Args()) < 1 {
    95  		return flag.ErrHelp
    96  	}
    97  
    98  	c, err := cmd.CnsClient()
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	result := lsResult{cmd: cmd}
   104  
   105  	for _, id := range f.Args() {
   106  		spec := types.CnsSnapshotQueryFilter{
   107  			SnapshotQuerySpecs: []types.CnsSnapshotQuerySpec{{
   108  				VolumeId: types.CnsVolumeId{
   109  					Id: id,
   110  				},
   111  			}},
   112  		}
   113  
   114  		for {
   115  			task, err := c.QuerySnapshots(ctx, spec)
   116  			if err != nil {
   117  				return err
   118  			}
   119  
   120  			info, err := cns.GetTaskInfo(ctx, task)
   121  			if err != nil {
   122  				return err
   123  			}
   124  
   125  			res, err := cns.GetQuerySnapshotsTaskResult(ctx, info)
   126  			if err != nil {
   127  				return err
   128  			}
   129  
   130  			for i, e := range res.Entries {
   131  				if e.Error != nil {
   132  					return errors.New(e.Error.LocalizedMessage)
   133  				}
   134  				result.Entries = append(result.Entries, &res.Entries[i])
   135  			}
   136  
   137  			if res.Cursor.Offset == res.Cursor.TotalRecords {
   138  				break
   139  			}
   140  
   141  			spec.Cursor = &res.Cursor
   142  		}
   143  	}
   144  
   145  	return cmd.WriteResult(&result)
   146  }