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

     1  /*
     2  Copyright (c) 2020-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 volume
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"fmt"
    23  	"io"
    24  	"log"
    25  	"text/tabwriter"
    26  
    27  	"github.com/vmware/govmomi/cns/types"
    28  	"github.com/vmware/govmomi/govc/cli"
    29  	"github.com/vmware/govmomi/govc/flags"
    30  	"github.com/vmware/govmomi/units"
    31  	vim "github.com/vmware/govmomi/vim25/types"
    32  )
    33  
    34  type ls struct {
    35  	*flags.ClientFlag
    36  	*flags.DatastoreFlag
    37  	*flags.OutputFlag
    38  
    39  	types.CnsQueryFilter
    40  
    41  	long bool
    42  	id   bool
    43  	disk bool
    44  }
    45  
    46  func init() {
    47  	cli.Register("volume.ls", &ls{})
    48  }
    49  
    50  func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) {
    51  	cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
    52  	cmd.ClientFlag.Register(ctx, f)
    53  
    54  	cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
    55  	cmd.DatastoreFlag.Register(ctx, f)
    56  
    57  	cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
    58  	cmd.OutputFlag.Register(ctx, f)
    59  
    60  	f.BoolVar(&cmd.long, "l", false, "Long listing format")
    61  	f.BoolVar(&cmd.id, "i", false, "List volume ID only")
    62  	f.BoolVar(&cmd.disk, "L", false, "List volume disk or file backing ID only")
    63  }
    64  
    65  func (cmd *ls) Process(ctx context.Context) error {
    66  	if err := cmd.ClientFlag.Process(ctx); err != nil {
    67  		return err
    68  	}
    69  	if err := cmd.DatastoreFlag.Process(ctx); err != nil {
    70  		return err
    71  	}
    72  	return cmd.OutputFlag.Process(ctx)
    73  }
    74  
    75  func (cmd *ls) Usage() string {
    76  	return "[ID...]"
    77  }
    78  
    79  func (cmd *ls) Description() string {
    80  	return `List CNS volumes.
    81  
    82  Examples:
    83    govc volume.ls
    84    govc volume.ls -l
    85    govc volume.ls -ds vsanDatastore
    86    govc volume.ls df86393b-5ae0-4fca-87d0-b692dbc67d45
    87    govc disk.ls -l $(govc volume.ls -L pvc-9744a4ff-07f4-43c4-b8ed-48ea7a528734)`
    88  }
    89  
    90  type lsWriter struct {
    91  	Volume []types.CnsVolume `json:"volume"`
    92  	cmd    *ls
    93  }
    94  
    95  func (r *lsWriter) Write(w io.Writer) error {
    96  	if r.cmd.id {
    97  		for _, volume := range r.Volume {
    98  			fmt.Fprintln(r.cmd.Out, volume.VolumeId.Id)
    99  		}
   100  		return nil
   101  	}
   102  
   103  	if r.cmd.disk {
   104  		for _, volume := range r.Volume {
   105  			var id string
   106  			switch backing := volume.BackingObjectDetails.(type) {
   107  			case *types.CnsBlockBackingDetails:
   108  				id = backing.BackingDiskId
   109  			case *types.CnsFileBackingDetails:
   110  				id = backing.BackingFileId
   111  			case *types.CnsVsanFileShareBackingDetails:
   112  				id = backing.Name
   113  			default:
   114  				log.Printf("%s unknown backing type: %T", volume.VolumeId.Id, backing)
   115  			}
   116  			fmt.Fprintln(r.cmd.Out, id)
   117  
   118  		}
   119  		return nil
   120  	}
   121  
   122  	tw := tabwriter.NewWriter(r.cmd.Out, 2, 0, 2, ' ', 0)
   123  
   124  	for _, volume := range r.Volume {
   125  		fmt.Printf("%s\t%s", volume.VolumeId.Id, volume.Name)
   126  		if r.cmd.long {
   127  			capacity := volume.BackingObjectDetails.GetCnsBackingObjectDetails().CapacityInMb
   128  			c := volume.Metadata.ContainerCluster
   129  			fmt.Printf("\t%s\t%s\t%s", units.ByteSize(capacity*1024*1024), c.ClusterType, c.ClusterId)
   130  		}
   131  		fmt.Println()
   132  	}
   133  
   134  	return tw.Flush()
   135  }
   136  
   137  func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error {
   138  	ds, err := cmd.DatastoreIfSpecified()
   139  	if err != nil {
   140  		return err
   141  	}
   142  
   143  	if ds != nil {
   144  		cmd.Datastores = []vim.ManagedObjectReference{ds.Reference()}
   145  	}
   146  
   147  	c, err := cmd.CnsClient()
   148  	if err != nil {
   149  		return err
   150  	}
   151  
   152  	for _, arg := range f.Args() {
   153  		cmd.VolumeIds = append(cmd.VolumeIds, types.CnsVolumeId{Id: arg})
   154  	}
   155  
   156  	var volumes []types.CnsVolume
   157  
   158  	for {
   159  		res, err := c.QueryVolume(ctx, cmd.CnsQueryFilter)
   160  		if err != nil {
   161  			return err
   162  		}
   163  
   164  		volumes = append(volumes, res.Volumes...)
   165  
   166  		if res.Cursor.Offset == res.Cursor.TotalRecords || len(res.Volumes) == 0 {
   167  			break
   168  		}
   169  
   170  		cmd.Cursor = &res.Cursor
   171  	}
   172  
   173  	return cmd.WriteResult(&lsWriter{volumes, cmd})
   174  }