This repository has been archived by the owner on Jan 21, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 262
/
vsphere.go
236 lines (191 loc) · 6.22 KB
/
vsphere.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
package vsphere // import "github.com/docker/infrakit/pkg/provider/vsphere"
import (
"context"
"errors"
"fmt"
"net/url"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
)
// Options capture the config parameters required to create the plugin
type Options struct {
VCenterURL string
DataCenter string
DataStore string
NetworkName string
VSphereHost string
IgnoreOnDestroy bool
}
type vCenter struct {
vCenterURL *string
dcName *string
dsName *string
networkName *string
vSphereHost *string
}
type vcInternal struct {
client *govmomi.Client
datastore *object.Datastore
dcFolders *object.DatacenterFolders
hostSystem *object.HostSystem
network object.NetworkReference
resourcePool *object.ResourcePool
}
type vmInstance struct {
// Used with LinuxKit ISOs
isoPath string
// Used with a VMware VM template
vmTemplate string
// TODO - Add in reading template from one DS and deploy to another
vmTemplateDatastore string
// Used by InfraKit to track group
groupTag string
// Folder that will store all InfraKit instances
instanceFolder string
// InfraKit vSphere instance settings
annotation string
vmPrefix string
vmName string
persistent string
persistentSz int
vCpus int
mem int
poweron bool
guestIP bool
}
func vCenterConnect(vc *vCenter) (vcInternal, error) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
var internals vcInternal
// Parse URL from string
u, err := url.Parse(*vc.vCenterURL)
if err != nil {
return internals, errors.New("URL can't be parsed, ensure it is https://username:password/<address>/sdk")
}
// Connect and log in to ESX or vCenter
internals.client, err = govmomi.NewClient(ctx, u, true)
if err != nil {
return internals, err
}
return internals, nil
}
func setInternalStructures(vc *vCenter, internals *vcInternal) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Create a new finder that will discover the defaults and are looked for Networks/Datastores
f := find.NewFinder(internals.client.Client, true)
// Find one and only datacenter, not sure how VMware linked mode will work
dc, err := f.DatacenterOrDefault(ctx, *vc.dcName)
if err != nil {
return fmt.Errorf("No Datacenter instance could be found inside of vCenter %v", err)
}
// Make future calls local to this datacenter
f.SetDatacenter(dc)
// Find Datastore/Network
internals.datastore, err = f.DatastoreOrDefault(ctx, *vc.dsName)
if err != nil {
return fmt.Errorf("Datastore [%s], could not be found", *vc.dsName)
}
internals.dcFolders, err = dc.Folders(ctx)
if err != nil {
return fmt.Errorf("Error locating default datacenter folder")
}
// Set the host that the VM will be created on
internals.hostSystem, err = f.HostSystemOrDefault(ctx, *vc.vSphereHost)
if err != nil {
return fmt.Errorf("vSphere host [%s], could not be found", *vc.vSphereHost)
}
// Find the resource pool attached to this host
internals.resourcePool, err = internals.hostSystem.ResourcePool(ctx)
if err != nil {
return fmt.Errorf("Error locating default resource pool")
}
return nil
}
func parseParameters(properties map[string]interface{}, p *plugin) (vmInstance, error) {
var newInstance vmInstance
log.Debug("Building vCenter specific parameters")
if *p.vC.vCenterURL == "" {
if properties["vCenterURL"] == nil {
return newInstance, errors.New("Environment variable VCURL or .yml vCenterURL must be set")
}
*p.vC.vCenterURL = properties["vCenterURL"].(string)
}
if properties["Datacenter"] == nil {
log.Warn("The property 'Datacenter' hasn't been set the API will choose the default, which could cause errors in Linked-Mode")
} else {
*p.vC.dcName = properties["Datacenter"].(string)
}
if properties["Datastore"] == nil {
return newInstance, errors.New("Property 'Datastore' must be set")
}
*p.vC.dsName = properties["Datastore"].(string)
log.Debug("Setting datastore", "datastore", *p.vC.dsName)
if properties["Hostname"] == nil {
return newInstance, errors.New("Property 'Hostname' must be set")
}
*p.vC.vSphereHost = properties["Hostname"].(string)
if properties["Network"] == nil {
log.Warn("The property 'Network' hasn't been set, no networks will be attached to VM")
} else {
*p.vC.networkName = properties["Network"].(string)
}
if properties["Annotation"] != nil {
newInstance.annotation = properties["Annotation"].(string)
}
if properties["vmPrefix"] == nil {
newInstance.vmPrefix = "vm"
} else {
newInstance.vmPrefix = properties["vmPrefix"].(string)
}
if properties["isoPath"] == nil {
log.Debug("The property 'isoPath' hasn't been set, bootable ISO will not be added to the VM")
} else {
newInstance.isoPath = properties["isoPath"].(string)
}
if properties["Template"] != nil {
newInstance.vmTemplate = properties["Template"].(string)
}
if properties["CPUs"] == nil {
newInstance.vCpus = 1
} else {
newInstance.vCpus = int(properties["CPUs"].(float64))
}
if properties["Memory"] == nil {
newInstance.mem = 512
} else {
newInstance.mem = int(properties["Memory"].(float64))
}
if properties["persistantSZ"] == nil {
newInstance.persistentSz = 0
} else {
newInstance.persistentSz = int(properties["persistantSZ"].(float64))
}
if properties["PowerOn"] == nil {
newInstance.poweron = false
} else {
newInstance.poweron = bool(properties["PowerOn"].(bool))
}
return newInstance, nil
}
func findNetwork(vc *vCenter, internals *vcInternal) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Create a new finder that will discover the defaults and are looked for Networks/Datastores
f := find.NewFinder(internals.client.Client, true)
// Find one and only datacenter, not sure how VMware linked mode will work
dc, err := f.DatacenterOrDefault(ctx, *vc.dcName)
if err != nil {
return fmt.Errorf("No Datacenter instance could be found inside of vCenter %v", err)
}
// Make future calls local to this datacenter
f.SetDatacenter(dc)
if *vc.networkName != "" {
internals.network, err = f.NetworkOrDefault(ctx, *vc.networkName)
if err != nil {
return fmt.Errorf("Network [%s], could not be found", *vc.networkName)
}
}
return nil
}