github.com/cloudfoundry-incubator/stembuild@v0.0.0-20211223202937-5b61d62226c6/commandparser/construct.go (about)

     1  package commandparser
     2  
     3  import (
     4  	"context"
     5  	"flag"
     6  	"fmt"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	vcenter_client_factory "github.com/cloudfoundry-incubator/stembuild/iaas_cli/iaas_clients/factory"
    11  	"github.com/cloudfoundry-incubator/stembuild/iaas_cli/iaas_clients/guest_manager"
    12  	"github.com/cloudfoundry-incubator/stembuild/iaas_cli/iaas_clients/vcenter_manager"
    13  	"github.com/vmware/govmomi/guest"
    14  	"github.com/vmware/govmomi/object"
    15  
    16  	"github.com/cloudfoundry-incubator/stembuild/construct/config"
    17  	"github.com/google/subcommands"
    18  )
    19  
    20  //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . VmConstruct
    21  type VmConstruct interface {
    22  	PrepareVM() error
    23  }
    24  
    25  //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . VCenterManager
    26  type VCenterManager interface {
    27  	OperationsManager(ctx context.Context, vm *object.VirtualMachine) *guest.OperationsManager
    28  	GuestManager(ctx context.Context, opsManager vcenter_manager.OpsManager, username, password string) (*guest_manager.GuestManager, error)
    29  	FindVM(ctx context.Context, inventoryPath string) (*object.VirtualMachine, error)
    30  	Login(ctx context.Context) error
    31  }
    32  
    33  //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . VMPreparerFactory
    34  type VMPreparerFactory interface {
    35  	VMPreparer(config config.SourceConfig, vCenterManager VCenterManager) (VmConstruct, error)
    36  }
    37  
    38  //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . ManagerFactory
    39  type ManagerFactory interface {
    40  	VCenterManager(ctx context.Context) (*vcenter_manager.VCenterManager, error)
    41  	SetConfig(config vcenter_client_factory.FactoryConfig)
    42  }
    43  
    44  //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . ConstructCmdValidator
    45  type ConstructCmdValidator interface {
    46  	PopulatedArgs(...string) bool
    47  	LGPOInDirectory() bool
    48  }
    49  
    50  //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . ConstructMessenger
    51  type ConstructMessenger interface {
    52  	ArgumentsNotProvided()
    53  	LGPONotFound()
    54  	CannotConnectToVM(err error)
    55  	CannotPrepareVM(err error)
    56  }
    57  
    58  type ConstructCmd struct {
    59  	ctx            context.Context
    60  	sourceConfig   config.SourceConfig
    61  	prepFactory    VMPreparerFactory
    62  	managerFactory ManagerFactory
    63  	validator      ConstructCmdValidator
    64  	messenger      ConstructMessenger
    65  	GlobalFlags    *GlobalFlags
    66  }
    67  
    68  func NewConstructCmd(ctx context.Context, prepFactory VMPreparerFactory, managerFactory ManagerFactory, validator ConstructCmdValidator, messenger ConstructMessenger) *ConstructCmd {
    69  	return &ConstructCmd{ctx: ctx, prepFactory: prepFactory, managerFactory: managerFactory, validator: validator, messenger: messenger}
    70  }
    71  
    72  func (*ConstructCmd) Name() string { return "construct" }
    73  func (*ConstructCmd) Synopsis() string {
    74  	return "Provisions and syspreps an existing VM on vCenter, ready to be packaged into a stemcell"
    75  }
    76  
    77  func (*ConstructCmd) Usage() string {
    78  	return fmt.Sprintf(`%[1]s construct -vm-ip <IP of VM> -vm-username <vm username> -vm-password <vm password>  -vcenter-url <vCenter URL> -vcenter-username <vCenter username> -vcenter-password <vCenter password> -vm-inventory-path <vCenter VM inventory path>
    79  
    80  Prepares a VM to be used by stembuild package. It leverages stemcell automation scripts to provision a VM to be used as a stemcell.
    81  
    82  Requirements:
    83  	LGPO.zip in current working directory
    84  	Running Windows VM with:
    85  		- Up to date Operating System
    86  		- Reachable by IP
    87  		- Username and password with Administrator privileges
    88  		- vCenter URL, username and password
    89  		- vCenter Inventory Path
    90  	The [vm-ip], [vm-username], [vm-password], [vcenter-url], [vcenter-username], [vcenter-password], [vm-inventory-path] must be specified
    91  
    92  Example:
    93  	%[1]s construct -vm-ip '10.0.0.5' -vm-username Admin -vm-password 'password' -vcenter-url vcenter.example.com -vcenter-username root -vcenter-password 'password' -vm-inventory-path '/datacenter/vm/folder/vm-name'
    94  
    95  Flags:
    96  `, filepath.Base(os.Args[0]))
    97  }
    98  
    99  func (p *ConstructCmd) SetFlags(f *flag.FlagSet) {
   100  	f.StringVar(&p.sourceConfig.GuestVmIp, "vm-ip", "", "IP of target machine")
   101  	f.StringVar(&p.sourceConfig.GuestVMUsername, "vm-username", "", "Username of target machine")
   102  	f.StringVar(&p.sourceConfig.GuestVMPassword, "vm-password", "", "Password of target machine. Needs to be wrapped in single quotations.")
   103  	f.StringVar(&p.sourceConfig.VCenterUrl, "vcenter-url", "", "vCenter url")
   104  	f.StringVar(&p.sourceConfig.VCenterUsername, "vcenter-username", "", "vCenter username")
   105  	f.StringVar(&p.sourceConfig.VCenterPassword, "vcenter-password", "", "vCenter password")
   106  	f.StringVar(&p.sourceConfig.VmInventoryPath, "vm-inventory-path", "", "vCenter VM inventory path. (e.g: <datacenter>/vm/<vm-folder>/<vm-name>)")
   107  	f.StringVar(&p.sourceConfig.CaCertFile, "vcenter-ca-certs", "", "filepath for custom ca certs")
   108  }
   109  
   110  func (p *ConstructCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
   111  	c := p.sourceConfig
   112  	if !p.validator.PopulatedArgs(c.GuestVmIp, c.GuestVMUsername, c.GuestVMPassword, c.VCenterUrl, c.VCenterUsername, c.VCenterPassword, c.VmInventoryPath) {
   113  		p.messenger.ArgumentsNotProvided()
   114  		return subcommands.ExitFailure
   115  	}
   116  	if !p.validator.LGPOInDirectory() {
   117  		p.messenger.LGPONotFound()
   118  		return subcommands.ExitFailure
   119  	}
   120  
   121  	p.managerFactory.SetConfig(vcenter_client_factory.FactoryConfig{
   122  		p.sourceConfig.VCenterUrl,
   123  		p.sourceConfig.VCenterUsername,
   124  		p.sourceConfig.VCenterPassword,
   125  		&vcenter_client_factory.ClientCreator{},
   126  		&vcenter_client_factory.GovmomiFinderCreator{},
   127  		p.sourceConfig.CaCertFile,
   128  	})
   129  
   130  	vCenterManager, err := p.managerFactory.VCenterManager(p.ctx)
   131  	if err != nil {
   132  		p.messenger.CannotPrepareVM(err)
   133  		return subcommands.ExitFailure
   134  	}
   135  
   136  	vmConstruct, err := p.prepFactory.VMPreparer(p.sourceConfig, vCenterManager)
   137  	if err != nil {
   138  		p.messenger.CannotPrepareVM(err)
   139  		return subcommands.ExitFailure
   140  	}
   141  
   142  	err = vmConstruct.PrepareVM()
   143  	if err != nil {
   144  		p.messenger.CannotPrepareVM(err)
   145  		return subcommands.ExitFailure
   146  	}
   147  
   148  	return subcommands.ExitSuccess
   149  }