Skip to content

Commit

Permalink
Merge pull request #2874 from Syuparn/issue-2873
Browse files Browse the repository at this point in the history
vcsim: Fix createVM to encode VM name
  • Loading branch information
dougm committed Jun 15, 2022
2 parents 70b89df + 578b95e commit 62e5b57
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 3 deletions.
12 changes: 9 additions & 3 deletions simulator/folder.go
Expand Up @@ -200,7 +200,7 @@ func (f *Folder) CreateFolder(ctx *Context, c *types.CreateFolder) soap.HasFault
r := &methods.CreateFolderBody{}

if folderHasChildType(&f.Folder, "Folder") {
name := f.escapeSpecialCharacters(c.Name)
name := escapeSpecialCharacters(c.Name)

if obj := ctx.Map.FindByName(name, f.ChildEntity); obj != nil {
r.Fault_ = Fault("", &types.DuplicateName{
Expand Down Expand Up @@ -228,7 +228,7 @@ func (f *Folder) CreateFolder(ctx *Context, c *types.CreateFolder) soap.HasFault
return r
}

func (f *Folder) escapeSpecialCharacters(name string) string {
func escapeSpecialCharacters(name string) string {
name = strings.ReplaceAll(name, `%`, strings.ToLower(url.QueryEscape(`%`)))
name = strings.ReplaceAll(name, `/`, strings.ToLower(url.QueryEscape(`/`)))
name = strings.ReplaceAll(name, `\`, strings.ToLower(url.QueryEscape(`\`)))
Expand Down Expand Up @@ -367,9 +367,15 @@ func hostsWithDatastore(hosts []types.ManagedObjectReference, path string) []typ
}

func (c *createVM) Run(task *Task) (types.AnyType, types.BaseMethodFault) {
config := &c.req.Config
// escape special characters in vm name
if config.Name != escapeSpecialCharacters(config.Name) {
deepCopy(c.req.Config, config)
config.Name = escapeSpecialCharacters(config.Name)
}

vm, err := NewVirtualMachine(c.ctx, c.Folder.Self, &c.req.Config)
if err != nil {
folderRemoveChild(c.ctx, &c.Folder.Folder, vm)
return nil, err
}

Expand Down
1 change: 1 addition & 0 deletions simulator/virtual_machine.go
Expand Up @@ -166,6 +166,7 @@ func NewVirtualMachine(ctx *Context, parent types.ManagedObjectReference, spec *
vm.Summary.OverallStatus = types.ManagedEntityStatusGreen
vm.ConfigStatus = types.ManagedEntityStatusGreen

// put vm in the folder only if no errors occurred
f, _ := asFolderMO(folder)
folderPutChild(ctx, f, vm)

Expand Down
69 changes: 69 additions & 0 deletions simulator/virtual_machine_test.go
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/simulator/esx"
"github.com/vmware/govmomi/task"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/types"
)

Expand Down Expand Up @@ -264,6 +265,74 @@ func TestCreateVm(t *testing.T) {
}
}

func TestCreateVmWithSpecialCharaters(t *testing.T) {
tests := []struct {
name string
expected string
}{
{`/`, `%2f`},
{`\`, `%5c`},
{`%`, `%25`},
// multiple special characters
{`%%`, `%25%25`},
// slash-separated name
{`foo/bar`, `foo%2fbar`},
}

for _, test := range tests {
m := ESX()

Test(func(ctx context.Context, c *vim25.Client) {
finder := find.NewFinder(c, false)

dc, err := finder.DefaultDatacenter(ctx)
if err != nil {
t.Fatal(err)
}

finder.SetDatacenter(dc)
folders, err := dc.Folders(ctx)
if err != nil {
t.Fatal(err)
}
vmFolder := folders.VmFolder

ds, err := finder.DefaultDatastore(ctx)
if err != nil {
t.Fatal(err)
}

spec := types.VirtualMachineConfigSpec{
Name: test.name,
Files: &types.VirtualMachineFileInfo{
VmPathName: fmt.Sprintf("[%s]", ds.Name()),
},
}

pool := object.NewResourcePool(c, esx.ResourcePool.Self)

task, err := vmFolder.CreateVM(ctx, spec, pool, nil)
if err != nil {
t.Fatal(err)
}

info, err := task.WaitForResult(ctx, nil)
if err != nil {
t.Fatal(err)
}

vm := object.NewVirtualMachine(c, info.Result.(types.ManagedObjectReference))
name, err := vm.ObjectName(ctx)
if err != nil {
t.Fatal(err)
}
if name != test.expected {
t.Errorf("expected %s, got %s", test.expected, name)
}
}, m)
}
}

func TestReconfigVmDevice(t *testing.T) {
ctx := context.Background()

Expand Down

0 comments on commit 62e5b57

Please sign in to comment.