generated from hashicorp/packer-plugin-scaffolding
-
Notifications
You must be signed in to change notification settings - Fork 90
/
driver.go
152 lines (131 loc) · 4.59 KB
/
driver.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package driver
import (
"context"
"fmt"
"net/url"
"time"
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/vapi/library"
"github.com/vmware/govmomi/vapi/rest"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
type Driver interface {
NewVM(ref *types.ManagedObjectReference) VirtualMachine
FindVM(name string) (VirtualMachine, error)
FindCluster(name string) (*Cluster, error)
PreCleanVM(ui packersdk.Ui, vmPath string, force bool, vsphereCluster string, vsphereHost string, vsphereResourcePool string) error
CreateVM(config *CreateConfig) (VirtualMachine, error)
NewDatastore(ref *types.ManagedObjectReference) Datastore
FindDatastore(name string, host string) (Datastore, error)
GetDatastoreName(id string) (string, error)
GetDatastoreFilePath(datastoreID, dir, filename string) (string, error)
NewFolder(ref *types.ManagedObjectReference) *Folder
FindFolder(name string) (*Folder, error)
NewHost(ref *types.ManagedObjectReference) *Host
FindHost(name string) (*Host, error)
NewNetwork(ref *types.ManagedObjectReference) *Network
FindNetwork(name string) (*Network, error)
FindNetworks(name string) ([]*Network, error)
NewResourcePool(ref *types.ManagedObjectReference) *ResourcePool
FindResourcePool(cluster string, host string, name string) (*ResourcePool, error)
FindContentLibraryByName(name string) (*Library, error)
FindContentLibraryItem(libraryId string, name string) (*library.Item, error)
FindContentLibraryFileDatastorePath(isoPath string) (string, error)
UpdateContentLibraryItem(item *library.Item, name string, description string) error
Cleanup() (error, error)
}
type VCenterDriver struct {
// context that controls the authenticated sessions used to run the VM commands
ctx context.Context
client *govmomi.Client
vimClient *vim25.Client
restClient *RestClient
finder *find.Finder
datacenter *object.Datacenter
}
func NewVCenterDriver(ctx context.Context, client *govmomi.Client, vimClient *vim25.Client, user *url.Userinfo, finder *find.Finder, datacenter *object.Datacenter) *VCenterDriver {
return &VCenterDriver{
ctx: ctx,
client: client,
vimClient: vimClient,
restClient: &RestClient{
client: rest.NewClient(vimClient),
credentials: user,
},
datacenter: datacenter,
finder: finder,
}
}
type ConnectConfig struct {
VCenterServer string
Username string
Password string
InsecureConnection bool
Datacenter string
}
func NewDriver(config *ConnectConfig) (Driver, error) {
ctx := context.TODO()
vcenterUrl, err := url.Parse(fmt.Sprintf("https://%v/sdk", config.VCenterServer))
if err != nil {
return nil, err
}
credentials := url.UserPassword(config.Username, config.Password)
vcenterUrl.User = credentials
soapClient := soap.NewClient(vcenterUrl, config.InsecureConnection)
vimClient, err := vim25.NewClient(ctx, soapClient)
if err != nil {
return nil, err
}
vimClient.RoundTripper = session.KeepAlive(vimClient.RoundTripper, 10*time.Minute)
client := &govmomi.Client{
Client: vimClient,
SessionManager: session.NewManager(vimClient),
}
err = client.SessionManager.Login(ctx, credentials)
if err != nil {
return nil, err
}
finder := find.NewFinder(client.Client, false)
datacenter, err := finder.DatacenterOrDefault(ctx, config.Datacenter)
if err != nil {
return nil, err
}
finder.SetDatacenter(datacenter)
d := &VCenterDriver{
ctx: ctx,
client: client,
vimClient: vimClient,
restClient: &RestClient{
client: rest.NewClient(vimClient),
credentials: credentials,
},
datacenter: datacenter,
finder: finder,
}
return d, nil
}
func (d *VCenterDriver) Cleanup() (error, error) {
return d.restClient.client.Logout(d.ctx), d.client.SessionManager.Logout(d.ctx)
}
// The rest.Client requires vCenter.
// RestClient is to modularize the rest.Client session and use it only when is necessary.
// This will allow users without vCenter Server to use the other features that do not use the rest.Client.
// To use the client login/logout must be done to create an authenticated session.
type RestClient struct {
client *rest.Client
credentials *url.Userinfo
}
func (r *RestClient) Login(ctx context.Context) error {
return r.client.Login(ctx, r.credentials)
}
func (r *RestClient) Logout(ctx context.Context) error {
return r.client.Logout(ctx)
}