github.com/vmware/govmomi@v0.51.0/cli/library/sync.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 library
     6  
     7  import (
     8  	"context"
     9  	"flag"
    10  	"fmt"
    11  
    12  	"github.com/vmware/govmomi/cli"
    13  	"github.com/vmware/govmomi/cli/flags"
    14  	"github.com/vmware/govmomi/vapi/library"
    15  	"github.com/vmware/govmomi/vapi/vcenter"
    16  )
    17  
    18  type sync struct {
    19  	*flags.FolderFlag
    20  	*flags.ResourcePoolFlag
    21  
    22  	force bool
    23  	vmtx  string
    24  }
    25  
    26  func init() {
    27  	cli.Register("library.sync", &sync{})
    28  }
    29  
    30  func (cmd *sync) Register(ctx context.Context, f *flag.FlagSet) {
    31  	cmd.FolderFlag, ctx = flags.NewFolderFlag(ctx)
    32  	cmd.FolderFlag.Register(ctx, f)
    33  
    34  	cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx)
    35  	cmd.ResourcePoolFlag.Register(ctx, f)
    36  
    37  	f.BoolVar(&cmd.force, "f", false, "Forcefully synchronize file content")
    38  	f.StringVar(&cmd.vmtx, "vmtx", "", "Sync subscribed library to local library as VM Templates")
    39  }
    40  
    41  func (cmd *sync) Process(ctx context.Context) error {
    42  	if err := cmd.FolderFlag.Process(ctx); err != nil {
    43  		return err
    44  	}
    45  	return cmd.ResourcePoolFlag.Process(ctx)
    46  }
    47  
    48  func (cmd *sync) Description() string {
    49  	return `Sync library NAME or ITEM.
    50  
    51  Examples:
    52    govc library.sync subscribed-library
    53    govc library.sync subscribed-library/item
    54    govc library.sync -vmtx local-library subscribed-library # convert subscribed OVFs to local VMTX`
    55  }
    56  
    57  func (cmd *sync) Usage() string {
    58  	return "NAME|ITEM"
    59  }
    60  
    61  func (cmd *sync) syncVMTX(ctx context.Context, m *library.Manager, src library.Library, dst library.Library, items ...library.Item) error {
    62  	if cmd.vmtx == "" {
    63  		return nil
    64  	}
    65  
    66  	pool, err := cmd.ResourcePool()
    67  	if err != nil {
    68  		return err
    69  	}
    70  
    71  	folder, err := cmd.Folder()
    72  	if err != nil {
    73  		return err
    74  	}
    75  
    76  	l := vcenter.TemplateLibrary{
    77  		Source:      src,
    78  		Destination: dst,
    79  		Placement: vcenter.Target{
    80  			FolderID:       folder.Reference().Value,
    81  			ResourcePoolID: pool.Reference().Value,
    82  		},
    83  		Include: func(item library.Item, current *library.Item) bool {
    84  			fmt.Printf("Syncing /%s/%s to /%s/%s...", src.Name, item.Name, dst.Name, item.Name)
    85  			if current == nil {
    86  				fmt.Println()
    87  				return true
    88  			}
    89  			fmt.Println("already exists.")
    90  			return false
    91  		},
    92  	}
    93  
    94  	return vcenter.NewManager(m.Client).SyncTemplateLibrary(ctx, l, items...)
    95  }
    96  
    97  func (cmd *sync) shouldSync(l library.Library) bool {
    98  	if cmd.vmtx == "" {
    99  		return true
   100  
   101  	}
   102  	// Allow library.sync -vmtx of LOCAL or SUBSCRIBED library
   103  	return l.Type == "SUBSCRIBED"
   104  }
   105  
   106  func (cmd *sync) Run(ctx context.Context, f *flag.FlagSet) error {
   107  	if f.NArg() != 1 {
   108  		return flag.ErrHelp
   109  	}
   110  	path := f.Arg(0)
   111  
   112  	c, err := cmd.FolderFlag.RestClient()
   113  	if err != nil {
   114  		return err
   115  	}
   116  
   117  	m := library.NewManager(c)
   118  
   119  	var local library.Library
   120  	if cmd.vmtx != "" {
   121  		l, err := flags.ContentLibrary(ctx, c, cmd.vmtx)
   122  		if err != nil {
   123  			return err
   124  		}
   125  		local = *l
   126  	}
   127  
   128  	res, err := flags.ContentLibraryResult(ctx, c, "", path)
   129  	if err != nil {
   130  		return err
   131  	}
   132  
   133  	fmt.Printf("Syncing %s...\n", path)
   134  
   135  	switch t := res.GetResult().(type) {
   136  	case library.Library:
   137  		if cmd.shouldSync(t) {
   138  			if err = m.SyncLibrary(ctx, &t); err != nil {
   139  				return err
   140  			}
   141  		}
   142  		return cmd.syncVMTX(ctx, m, t, local)
   143  	case library.Item:
   144  		lib := res.GetParent().GetResult().(library.Library)
   145  		if cmd.shouldSync(lib) {
   146  			if err = m.SyncLibraryItem(ctx, &t, cmd.force); err != nil {
   147  				return err
   148  			}
   149  		}
   150  		return cmd.syncVMTX(ctx, m, lib, local, t)
   151  	default:
   152  		return fmt.Errorf("%q is a %T", res.GetPath(), t)
   153  	}
   154  }