Skip to content

Commit ee9e662

Browse files
authored
Merge pull request #1651 from ioito/automated-cherry-pick-of-#1650-upstream-release-4.0
Automated cherry pick of #1650: fix(esxi): support vm folder
2 parents 5dede50 + 971071d commit ee9e662

File tree

4 files changed

+193
-32
lines changed

4 files changed

+193
-32
lines changed

pkg/multicloud/esxi/host.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ type SCreateVMParam struct {
783783
Cdrom SCdromInfo
784784
Disks []SDiskInfo
785785
Nics []jsonutils.JSONObject
786-
ResourcePool string
786+
ProjectId string
787787
InstanceSnapshotInfo SEsxiInstanceSnapshotInfo
788788
EnableEsxiSwap bool
789789
}
@@ -1158,19 +1158,19 @@ func (host *SHost) DoCreateVM(ctx context.Context, ds *SDatastore, params SCreat
11581158
err = errors.Wrapf(err, "SHost.GetDatacenter for host '%s'", host.GetId())
11591159
return
11601160
}
1161-
// get vmFloder
1162-
folders, err := dc.getObjectDatacenter().Folders(ctx)
1161+
1162+
vmFolder, err := dc.GetFolder(params.ProjectId)
11631163
if err != nil {
1164-
err = errors.Wrap(err, "object.DataCenter.Folders")
1164+
err = errors.Wrap(err, "GetFolder")
11651165
return
11661166
}
1167-
vmFolder := folders.VmFolder
1168-
resourcePool, err := host.SyncResourcePool(params.ResourcePool)
1167+
1168+
pool, err := host.GetResourcePool()
11691169
if err != nil {
1170-
err = errors.Wrap(err, "SyncResourcePool")
1170+
err = errors.Wrap(err, "GetResourcePool")
11711171
return
11721172
}
1173-
task, err := vmFolder.CreateVM(ctx, spec, resourcePool, host.GetHostSystem())
1173+
task, err := vmFolder.CreateVM(ctx, spec, pool, host.GetHostSystem())
11741174
if err != nil {
11751175
err = errors.Wrap(err, "VmFolder.Create")
11761176
return
@@ -1283,26 +1283,26 @@ func (host *SHost) CloneVM(ctx context.Context, from *SVirtualMachine, snapshot
12831283
if err != nil {
12841284
return nil, errors.Wrapf(err, "SHost.GetDatacenter for host '%s'", host.GetId())
12851285
}
1286-
// get vmFloder
1287-
folders, err := dc.getObjectDatacenter().Folders(ctx)
1286+
vmFolder, err := dc.GetFolder(params.ProjectId)
12881287
if err != nil {
1289-
return nil, errors.Wrap(err, "object.DataCenter.Folders")
1288+
return nil, errors.Wrap(err, "GetFolder")
12901289
}
1291-
resourcePool, err := host.SyncResourcePool(params.ResourcePool)
1290+
1291+
resourcePool, err := host.GetResourcePool()
12921292
if err != nil {
1293-
return nil, errors.Wrap(err, "SyncResourcePool")
1293+
return nil, errors.Wrap(err, "GetResourcePool")
12941294
}
12951295

1296-
folderref := folders.VmFolder.Reference()
12971296
poolref := resourcePool.Reference()
12981297
hostref := host.GetHostSystem().Reference()
12991298
tds, err := ds.getDatastoreObj(ctx)
13001299
if err != nil {
13011300
return nil, errors.Wrapf(err, "getDatastoreObj")
13021301
}
13031302
dsref := tds.Reference()
1303+
vmFolderRef := vmFolder.Reference()
13041304
relocateSpec := types.VirtualMachineRelocateSpec{
1305-
Folder: &folderref,
1305+
Folder: &vmFolderRef,
13061306
Pool: &poolref,
13071307
Host: &hostref,
13081308
Datastore: &dsref,
@@ -1352,7 +1352,7 @@ func (host *SHost) CloneVM(ctx context.Context, from *SVirtualMachine, snapshot
13521352
})
13531353
}
13541354
cloneSpec.Config = &spec
1355-
task, err := ovm.Clone(ctx, folders.VmFolder, name, *cloneSpec)
1355+
task, err := ovm.Clone(ctx, vmFolder, name, *cloneSpec)
13561356
if err != nil {
13571357
return nil, errors.Wrap(err, "object.VirtualMachine.Clone")
13581358
}

pkg/multicloud/esxi/manager.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -586,22 +586,6 @@ func findDatacenterByMoId(dcs []*SDatacenter, dcId string) (*SDatacenter, error)
586586
return nil, cloudprovider.ErrNotFound
587587
}
588588

589-
func (cli *SESXiClient) GetIProjects() ([]cloudprovider.ICloudProject, error) {
590-
dcs, err := cli.GetDatacenters()
591-
if err != nil {
592-
return nil, errors.Wrap(err, "GetDatacenters")
593-
}
594-
ret := []cloudprovider.ICloudProject{}
595-
for i := 0; i < len(dcs); i++ {
596-
iprojects, err := dcs[i].GetResourcePools()
597-
if err != nil {
598-
return nil, errors.Wrap(err, "GetResourcePools")
599-
}
600-
ret = append(ret, iprojects...)
601-
}
602-
return ret, nil
603-
}
604-
605589
func (cli *SESXiClient) FindHostByMoId(moId string) (cloudprovider.ICloudHost, error) {
606590
dcs, err := cli.GetDatacenters()
607591
if err != nil {

pkg/multicloud/esxi/project.go

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Copyright 2019 Yunion
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package esxi
16+
17+
import (
18+
"context"
19+
20+
"github.com/vmware/govmomi/object"
21+
api "yunion.io/x/cloudmux/pkg/apis/compute"
22+
"yunion.io/x/cloudmux/pkg/cloudprovider"
23+
"yunion.io/x/cloudmux/pkg/multicloud"
24+
"yunion.io/x/pkg/errors"
25+
)
26+
27+
type SProject struct {
28+
multicloud.SProjectBase
29+
multicloud.STagBase
30+
31+
client *SESXiClient
32+
folder *object.Folder
33+
34+
Name string
35+
Id string
36+
}
37+
38+
func (project *SProject) GetId() string {
39+
return project.Id
40+
}
41+
42+
func (project *SProject) GetGlobalId() string {
43+
return project.Id
44+
}
45+
46+
func (project *SProject) GetName() string {
47+
return project.Name
48+
}
49+
50+
func (project *SProject) GetStatus() string {
51+
return api.EXTERNAL_PROJECT_STATUS_AVAILABLE
52+
}
53+
54+
func (cli *SESXiClient) listAllFolders(ctx context.Context, folder *object.Folder, prefix string) ([]SProject, error) {
55+
ret := []SProject{}
56+
name, err := folder.ObjectName(ctx)
57+
if err != nil {
58+
return nil, errors.Wrap(err, "ObjectName")
59+
}
60+
if len(prefix) > 0 {
61+
name = prefix + name
62+
}
63+
ret = append(ret, SProject{
64+
folder: folder,
65+
Id: folder.Reference().Value,
66+
Name: name,
67+
})
68+
69+
children, err := folder.Children(ctx)
70+
if err != nil {
71+
return nil, errors.Wrap(err, "Children")
72+
}
73+
74+
for _, child := range children {
75+
if subFolder, ok := child.(*object.Folder); ok {
76+
folders, err := cli.listAllFolders(ctx, subFolder, name+"|")
77+
if err != nil {
78+
return nil, errors.Wrap(err, "listAllFolders")
79+
}
80+
ret = append(ret, folders...)
81+
}
82+
}
83+
return ret, nil
84+
}
85+
86+
func (dc *SDatacenter) GetVMFolders() ([]SProject, error) {
87+
vmFolders, err := dc.getObjectDatacenter().Folders(dc.manager.context)
88+
if err != nil {
89+
return nil, errors.Wrap(err, "Folders")
90+
}
91+
ret, err := dc.manager.listAllFolders(dc.manager.context, vmFolders.VmFolder, "")
92+
if err != nil {
93+
return nil, errors.Wrap(err, "listAllFolders")
94+
}
95+
return ret, nil
96+
}
97+
98+
func (dc *SDatacenter) GetFolder(folderId string) (*object.Folder, error) {
99+
vmFolders, err := dc.getObjectDatacenter().Folders(dc.manager.context)
100+
if err != nil {
101+
return nil, errors.Wrap(err, "Folders")
102+
}
103+
ret, err := dc.manager.listAllFolders(dc.manager.context, vmFolders.VmFolder, "")
104+
if err != nil {
105+
return nil, errors.Wrap(err, "listAllFolders")
106+
}
107+
for i := range ret {
108+
if ret[i].Id == folderId {
109+
return ret[i].folder, nil
110+
}
111+
}
112+
return vmFolders.VmFolder, nil
113+
}
114+
115+
func (cli *SESXiClient) GetVMFolders() ([]SProject, error) {
116+
dcs, err := cli.GetDatacenters()
117+
if err != nil {
118+
return nil, errors.Wrap(err, "GetDatacenters")
119+
}
120+
ret := make([]SProject, 0)
121+
for i := range dcs {
122+
folders, err := dcs[i].GetVMFolders()
123+
if err != nil {
124+
return nil, errors.Wrap(err, "GetVMFolders")
125+
}
126+
ret = append(ret, folders...)
127+
}
128+
return ret, nil
129+
}
130+
131+
func (cli *SESXiClient) GetIProjects() ([]cloudprovider.ICloudProject, error) {
132+
projects, err := cli.GetVMFolders()
133+
if err != nil {
134+
return nil, errors.Wrap(err, "GetVMFolders")
135+
}
136+
ret := make([]cloudprovider.ICloudProject, 0)
137+
for i := range projects {
138+
projects[i].client = cli
139+
ret = append(ret, &projects[i])
140+
}
141+
return ret, nil
142+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2019 Yunion
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package shell
16+
17+
import (
18+
"yunion.io/x/pkg/util/printutils"
19+
"yunion.io/x/pkg/util/shellutils"
20+
21+
"yunion.io/x/cloudmux/pkg/multicloud/esxi"
22+
)
23+
24+
func init() {
25+
type ProjectListOptions struct {
26+
}
27+
shellutils.R(&ProjectListOptions{}, "project-list", "List all projects", func(cli *esxi.SESXiClient, args *ProjectListOptions) error {
28+
projects, err := cli.GetVMFolders()
29+
if err != nil {
30+
return err
31+
}
32+
printutils.PrintInterfaceList(projects, 0, 0, 0, []string{"Name", "Id"})
33+
return nil
34+
})
35+
}

0 commit comments

Comments
 (0)