github.com/vmware/govmomi@v0.37.2/govc/library/sync.go (about)

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