Skip to content

Commit 1ea8672

Browse files
committed
WIP
Signed-off-by: Dainius Serplis <dserplis@vmware.com>
1 parent 2e4e75f commit 1ea8672

File tree

8 files changed

+109
-6
lines changed

8 files changed

+109
-6
lines changed

govcd/catalog.go

+30
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,36 @@ func (cat *Catalog) UploadOvfByLink(ovfUrl, itemName, description string) (Task,
360360
return task, nil
361361
}
362362

363+
// CaptureVappTemplate captures a vApp template from an existing vApp
364+
func (cat *Catalog) CaptureVappTemplate(captureParams *types.CaptureVAppParams) (*VAppTemplate, error) {
365+
task, err := cat.CaptureVappTemplateAsync(captureParams)
366+
if err != nil {
367+
return nil, err
368+
}
369+
370+
err = task.WaitTaskCompletion()
371+
if err != nil {
372+
return nil, err
373+
}
374+
375+
// After the task is finished, owner field contains the resulting vApp template
376+
return cat.GetVappTemplateByHref(task.Task.Owner.HREF)
377+
}
378+
379+
func (cat *Catalog) CaptureVappTemplateAsync(captureParams *types.CaptureVAppParams) (Task, error) {
380+
util.Logger.Printf("[TRACE] Capturing vApp template to catalog %s", cat.Catalog.Name)
381+
captureTemplateHref := cat.client.VCDHREF
382+
captureTemplateHref.Path += fmt.Sprintf("/catalog/%s/action/captureVApp", extractUuid(cat.Catalog.ID))
383+
384+
captureParams.Xmlns = types.XMLNamespaceVCloud
385+
captureParams.XmlnsNs0 = types.XMLNamespaceOVF
386+
387+
util.Logger.Printf("[TRACE] Url for capturing vApp template: %s", captureTemplateHref.String())
388+
389+
return cat.client.ExecuteTaskRequest(captureTemplateHref.String(), http.MethodPost,
390+
types.MimeCaptureVappTemplateParams, "error capturing vApp Template: %s", captureParams)
391+
}
392+
363393
// Upload files for vCD created upload links. Different approach then vmdk file are
364394
// chunked (e.g. test.vmdk.000000000, test.vmdk.000000001 or test.vmdk). vmdk files are chunked if
365395
// in description file attribute ChunkSize is not zero.

govcd/catalog_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -1490,3 +1490,34 @@ func (vcd *TestVCD) Test_CatalogCreateCompleteness(check *C) {
14901490
err = catalog.Delete(true, true)
14911491
check.Assert(err, IsNil)
14921492
}
1493+
1494+
func (vcd *TestVCD) Test_CaptureVapp(check *C) {
1495+
fmt.Printf("Running: %s\n", check.TestName())
1496+
1497+
vapp, vm := createNsxtVAppAndVm(vcd, check)
1498+
check.Assert(vapp, NotNil)
1499+
check.Assert(vm, NotNil)
1500+
1501+
// retrieve NSX-T Catalog
1502+
cat, err := vcd.org.GetCatalogByName(vcd.config.VCD.Catalog.NsxtBackedCatalogName, false)
1503+
check.Assert(err, IsNil)
1504+
check.Assert(cat, NotNil)
1505+
1506+
vAppCaptureParams := &types.CaptureVAppParams{
1507+
Name: check.TestName() + "vm-template",
1508+
Source: &types.Reference{
1509+
HREF: vapp.VApp.HREF,
1510+
},
1511+
CustomizationSection: types.CaptureVAppParamsCustomizationSection{
1512+
Info: "CustomizeOnInstantiate Settings",
1513+
CustomizeOnInstantiate: true,
1514+
},
1515+
CopyTpmOnInstantiate: addrOf(false),
1516+
}
1517+
1518+
templ, err := cat.CaptureVappTemplate(vAppCaptureParams)
1519+
check.Assert(err, IsNil)
1520+
check.Assert(templ, NotNil)
1521+
1522+
AddToCleanupList(templ.VAppTemplate.Name, "catalogItem", vcd.org.Org.Name+"|"+vcd.config.VCD.Catalog.NsxtBackedCatalogName, "Test_UploadOvf")
1523+
}

govcd/org.go

+14
Original file line numberDiff line numberDiff line change
@@ -600,3 +600,17 @@ func queryCatalogList(client *Client, filterFields map[string]string) ([]*types.
600600
util.Logger.Printf("[DEBUG] QueryCatalogList returned with : %#v and error: %s", catalogs, err)
601601
return catalogs, nil
602602
}
603+
604+
// GetVappByHref returns a vApp reference by running a vCD API call
605+
// If no valid vApp is found, it returns a nil VApp reference and an error
606+
func (org *Org) GetVAppByHref(vappHref string) (*VApp, error) {
607+
newVapp := NewVApp(org.client)
608+
609+
_, err := org.client.ExecuteRequest(vappHref, http.MethodGet,
610+
"", "error retrieving vApp: %s", nil, newVapp.VApp)
611+
612+
if err != nil {
613+
return nil, err
614+
}
615+
return newVapp, nil
616+
}

govcd/vapp.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ type DhcpSettings struct {
6060
}
6161

6262
// Returns the vdc where the vapp resides in.
63-
func (vapp *VApp) getParentVDC() (Vdc, error) {
63+
func (vapp *VApp) GetParentVDC() (Vdc, error) {
6464
for _, link := range vapp.VApp.Link {
6565
if (link.Type == types.MimeVDC || link.Type == types.MimeAdminVDC) && link.Rel == "up" {
6666

@@ -620,7 +620,7 @@ func (vapp *VApp) ChangeStorageProfile(name string) (Task, error) {
620620
return Task{}, fmt.Errorf("vApp doesn't contain any children, interrupting customization")
621621
}
622622

623-
vdc, err := vapp.getParentVDC()
623+
vdc, err := vapp.GetParentVDC()
624624
if err != nil {
625625
return Task{}, fmt.Errorf("error retrieving parent VDC for vApp %s", vapp.VApp.Name)
626626
}
@@ -1442,7 +1442,7 @@ func (vapp *VApp) getOrgInfo() (*TenantContext, error) {
14421442
return previous, nil
14431443
}
14441444
var err error
1445-
vdc, err := vapp.getParentVDC()
1445+
vdc, err := vapp.GetParentVDC()
14461446
if err != nil {
14471447
return nil, err
14481448
}
@@ -1514,7 +1514,7 @@ func (vapp *VApp) Rename(newName string) error {
15141514
}
15151515

15161516
func (vapp *VApp) getTenantContext() (*TenantContext, error) {
1517-
parentVdc, err := vapp.getParentVDC()
1517+
parentVdc, err := vapp.GetParentVDC()
15181518
if err != nil {
15191519
return nil, err
15201520
}

govcd/vapp_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (vcd *TestVCD) TestGetParentVDC(check *C) {
2929
vapp, err := vcd.vdc.GetVAppByName(vcd.vapp.VApp.Name, false)
3030
check.Assert(err, IsNil)
3131

32-
vdc, err := vapp.getParentVDC()
32+
vdc, err := vapp.GetParentVDC()
3333

3434
check.Assert(err, IsNil)
3535
check.Assert(vdc.Vdc.Name, Equals, vcd.vdc.Vdc.Name)

govcd/vm.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ func (vm *VM) GetParentVdc() (*Vdc, error) {
925925
return nil, fmt.Errorf("could not find parent vApp for VM %s: %s", vm.VM.Name, err)
926926
}
927927

928-
vdc, err := vapp.getParentVDC()
928+
vdc, err := vapp.GetParentVDC()
929929
if err != nil {
930930
return nil, fmt.Errorf("could not find parent vApp for VM %s: %s", vm.VM.Name, err)
931931
}

types/v56/constants.go

+2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ const (
101101
MimeVM = "application/vnd.vmware.vcloud.vm+xml"
102102
// Mime for instantiate vApp template params
103103
MimeInstantiateVappTemplateParams = "application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml"
104+
// Mime for capture vApp into template
105+
MimeCaptureVappTemplateParams = "application/vnd.vmware.vcloud.captureVAppParams+xml"
104106
// Mime for clone vApp template params
105107
MimeCloneVapp = "application/vnd.vmware.vcloud.cloneVAppParams+xml"
106108
// Mime for product section

types/v56/types.go

+26
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,32 @@ type VAppTemplateForUpdate struct {
16041604
Description string `xml:"Description,omitempty"` // Optional description.
16051605
}
16061606

1607+
type CaptureVAppParams struct {
1608+
XMLName xml.Name `xml:"CaptureVAppParams"`
1609+
1610+
Xmlns string `xml:"xmlns,attr"`
1611+
XmlnsNs0 string `xml:"xmlns:ns0,attr,omitempty"`
1612+
1613+
Name string `xml:"name,attr"`
1614+
Description string `xml:"Description,omitempty"`
1615+
Source *Reference `xml:"Source"`
1616+
// CaptureVmParams struct {
1617+
// Name string `xml:"name,attr,omitempty"`
1618+
// Description string `xml:"Description,omitempty"`
1619+
// Source *Reference `xml:"Source"`
1620+
// VdcComputePolicy *Reference `xml:"VdcComputePolicy"`
1621+
// } `xml:"CaptureVmParams,omitempty"`
1622+
// Section string `xml:"Section"`
1623+
CustomizationSection CaptureVAppParamsCustomizationSection `xml:"CustomizationSection"`
1624+
TargetCatalogItem *Reference `xml:"TargetCatalogItem,omitempty"`
1625+
CopyTpmOnInstantiate *bool `xml:"CopyTpmOnInstantiate"`
1626+
}
1627+
1628+
type CaptureVAppParamsCustomizationSection struct {
1629+
Info string `xml:"ns0:Info,omitempty"`
1630+
CustomizeOnInstantiate bool `xml:"CustomizeOnInstantiate"`
1631+
}
1632+
16071633
// VMDiskChange represents a virtual machine only with Disk setting update part
16081634
type VMDiskChange struct {
16091635
XMLName xml.Name `xml:"Vm"`

0 commit comments

Comments
 (0)