github.com/vmware/govmomi@v0.37.1/govc/volume/snapshot/ls.go (about)

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