Commit ee23d672 authored by Bobby DeVeaux's avatar Bobby DeVeaux
Browse files

adding vdc creation

updating types + tests
parent b1bffe67
Showing with 708 additions and 64 deletions
+708 -64
...@@ -29,8 +29,12 @@ core-dev: generate ...@@ -29,8 +29,12 @@ core-dev: generate
# Shorthand for quickly testing the core of Terraform (i.e. "not providers") # Shorthand for quickly testing the core of Terraform (i.e. "not providers")
core-test: generate core-test: generate
@echo "Testing core packages..." && \ @echo "Testing core packages..." && \
go test -tags 'core' $(TESTARGS) $(shell go list ./... | grep -v -E 'terraform/(builtin|vendor)') go test -tags `core` $(TESTARGS) $(shell go list ./... | grep -v -E `terraform/(builtin|vendor)`)
get-deps:
@echo "==> Fetching dependencies"
@go get -v $(TEST)
# Shorthand for building and installing just one plugin for local testing. # Shorthand for building and installing just one plugin for local testing.
# Run as (for example): make plugin-dev PLUGIN=provider-aws # Run as (for example): make plugin-dev PLUGIN=provider-aws
plugin-dev: generate plugin-dev: generate
......
...@@ -60,11 +60,12 @@ func Provider() terraform.ResourceProvider { ...@@ -60,11 +60,12 @@ func Provider() terraform.ResourceProvider {
}, },
ResourcesMap: map[string]*schema.Resource{ ResourcesMap: map[string]*schema.Resource{
"vcd_network": resourceVcdNetwork(), "vcd_network": resourceVcdNetwork(),
"vcd_vapp": resourceVcdVApp(), "vcd_vapp": resourceVcdVApp(),
"vcd_firewall_rules": resourceVcdFirewallRules(), "vcd_firewall_rules": resourceVcdFirewallRules(),
"vcd_dnat": resourceVcdDNAT(), "vcd_dnat": resourceVcdDNAT(),
"vcd_snat": resourceVcdSNAT(), "vcd_snat": resourceVcdSNAT(),
"vcd_edgegateway_vpn": resourceVcdEdgeGatewayVpn(),
}, },
ConfigureFunc: providerConfigure, ConfigureFunc: providerConfigure,
......
package vcd
import (
"log"
"fmt"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
types "github.com/ukcloud/govcloudair/types/v56"
)
func resourceVcdEdgeGatewayVpn() *schema.Resource {
return &schema.Resource{
Create: resourceVcdEdgeGatewayVpnCreate,
Read: resourceVcdEdgeGatewayVpnRead,
Delete: resourceVcdEdgeGatewayVpnDelete,
Schema: map[string]*schema.Schema{
"edge_gateway": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"description": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"encryption_protocol": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"local_ip_address": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"local_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"mtu": &schema.Schema{
Type: schema.TypeInt,
Required: true,
ForceNew: true,
},
"peer_ip_address": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"peer_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"shared_secret": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"local_subnets": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"local_subnet_name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"local_subnet_gateway": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"local_subnet_mask": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
},
},
},
"peer_subnets": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"peer_subnet_name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"peer_subnet_gateway": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"peer_subnet_mask": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
},
},
},
},
}
}
func resourceVcdEdgeGatewayVpnCreate(d *schema.ResourceData, meta interface{}) error {
vcdClient := meta.(*VCDClient)
log.Printf("[TRACE] CLIENT: %#v", vcdClient)
vcdClient.Mutex.Lock()
defer vcdClient.Mutex.Unlock()
edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
localSubnetsList := d.Get("local_subnets").(*schema.Set).List()
peerSubnetsList := d.Get("peer_subnets").(*schema.Set).List()
localSubnets := make([]*types.IpsecVpnSubnet, len(localSubnetsList))
peerSubnets := make([]*types.IpsecVpnSubnet, len(peerSubnetsList))
for i, s := range localSubnetsList {
ls := s.(map[string]interface{})
localSubnets[i] = &types.IpsecVpnSubnet{
Name: ls["local_subnet_name"].(string),
Gateway: ls["local_subnet_gateway"].(string),
Netmask: ls["local_subnet_mask"].(string),
}
}
for i, s := range peerSubnetsList {
ls := s.(map[string]interface{})
peerSubnets[i] = &types.IpsecVpnSubnet{
Name: ls["peer_subnet_name"].(string),
Gateway: ls["peer_subnet_gateway"].(string),
Netmask: ls["peer_subnet_mask"].(string),
}
}
tunnel := &types.GatewayIpsecVpnTunnel{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
IpsecVpnLocalPeer: &types.IpsecVpnLocalPeer{
ID: "",
Name: "",
},
EncryptionProtocol: d.Get("encryption_protocol").(string),
LocalIPAddress: d.Get("local_ip_address").(string),
LocalID: d.Get("local_id").(string),
LocalSubnet: localSubnets,
Mtu: d.Get("mtu").(int),
PeerID: d.Get("peer_id").(string),
PeerIPAddress: d.Get("peer_ip_address").(string),
PeerSubnet: peerSubnets,
SharedSecret: d.Get("shared_secret").(string),
IsEnabled: true,
}
tunnels := make([]*types.GatewayIpsecVpnTunnel, 1)
tunnels[0] = tunnel
ipsecVPNConfig := &types.EdgeGatewayServiceConfiguration{
Xmlns: "http://www.vmware.com/vcloud/v1.5",
GatewayIpsecVpnService: &types.GatewayIpsecVpnService{
IsEnabled: true,
/*
Endpoint: &types.GatewayIpsecVpnEndpoint{
Network: &types.Reference{
HREF: "http://myvpn.com",
},
PublicIP: "63.30.253.57",
},
*/
Tunnel: tunnels,
},
}
log.Printf("[INFO] ipsecVPNConfig: %#v", ipsecVPNConfig)
err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError {
edgeGateway.Refresh()
task, err := edgeGateway.AddIpsecVPN(ipsecVPNConfig)
if err != nil {
log.Printf("[INFO] Error setting ipsecVPNConfig rules: %s", err)
return resource.RetryableError(
fmt.Errorf("Error setting ipsecVPNConfig rules: %#v", err))
}
return resource.RetryableError(task.WaitTaskCompletion())
})
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
}
d.SetId(d.Get("edge_gateway").(string))
return resourceVcdEdgeGatewayVpnRead(d, meta)
}
func resourceVcdEdgeGatewayVpnDelete(d *schema.ResourceData, meta interface{}) error {
vcdClient := meta.(*VCDClient)
log.Printf("[TRACE] CLIENT: %#v", vcdClient)
vcdClient.Mutex.Lock()
defer vcdClient.Mutex.Unlock()
edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
ipsecVPNConfig := &types.EdgeGatewayServiceConfiguration{
Xmlns: "http://www.vmware.com/vcloud/v1.5",
GatewayIpsecVpnService: &types.GatewayIpsecVpnService{
IsEnabled: false,
},
}
log.Printf("[INFO] ipsecVPNConfig: %#v", ipsecVPNConfig)
err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError {
edgeGateway.Refresh()
task, err := edgeGateway.AddIpsecVPN(ipsecVPNConfig)
if err != nil {
log.Printf("[INFO] Error setting ipsecVPNConfig rules: %s", err)
return resource.RetryableError(
fmt.Errorf("Error setting ipsecVPNConfig rules: %#v", err))
}
return resource.RetryableError(task.WaitTaskCompletion())
})
if err != nil {
return fmt.Errorf("Error completing tasks: %#v", err)
}
d.SetId(d.Get("edge_gateway").(string))
if err != nil {
return fmt.Errorf("Error finding edge gateway: %#v", err)
}
return nil
}
func resourceVcdEdgeGatewayVpnRead(d *schema.ResourceData, meta interface{}) error {
vcdClient := meta.(*VCDClient)
edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
if err != nil {
return fmt.Errorf("Error finding edge gateway: %#v", err)
}
fmt.Println(edgeGateway)
//d.Set("name", *edgeGateway.EdgeGateway.Configuration.EdgeGatewayServiceConfiguration.GatewayIpsecVpnService.Tunnel[0].Name)
// and all the others
return nil
}
TEST?=./...
GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor)
default: fmt test testrace vet
# test runs the test suite and vets the code
test: get-deps fmtcheck
@golint ./...
@echo "==> Running Tests"
@go list $(TEST) | xargs -n1 go test -timeout=60s -parallel=10 $(TESTARGS)
# testrace runs the race checker
testrace:
@go list $(TEST) | xargs -n1 go test -race $(TESTARGS)
# vet runs the Go source code static analysis tool `vet` to find
# any common errors.
vet:
@echo "==> Running Go Vet"
@go vet $$(go list ./... | grep -v vendor/) ; if [ $$? -eq 1 ]; then \
echo ""; \
echo "Vet found suspicious constructs. Please check the reported constructs"; \
echo "and fix them if necessary before submitting the code for review."; \
exit 1; \
fi
get-deps:
@echo "==> Fetching dependencies"
@go get -v $(TEST)
@go get -u github.com/golang/lint/golint
fmt:
gofmt -w $(GOFMT_FILES)
fmtcheck:
@sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'"
\ No newline at end of file
...@@ -115,6 +115,10 @@ func (e *EdgeGateway) AddDhcpPool(network *types.OrgVDCNetwork, dhcppool []inter ...@@ -115,6 +115,10 @@ func (e *EdgeGateway) AddDhcpPool(network *types.OrgVDCNetwork, dhcppool []inter
} }
func (e *EdgeGateway) RemoveNATMapping(nattype, externalIP, internalIP, port string) (Task, error) { func (e *EdgeGateway) RemoveNATMapping(nattype, externalIP, internalIP, port string) (Task, error) {
return e.RemoveNATPortMapping(nattype, externalIP, port, internalIP, port)
}
func (e *EdgeGateway) RemoveNATPortMapping(nattype, externalIP, externalPort string, internalIP, internalPort string) (Task, error) {
// Find uplink interface // Find uplink interface
var uplink types.Reference var uplink types.Reference
for _, gi := range e.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface { for _, gi := range e.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface {
...@@ -140,7 +144,7 @@ func (e *EdgeGateway) RemoveNATMapping(nattype, externalIP, internalIP, port str ...@@ -140,7 +144,7 @@ func (e *EdgeGateway) RemoveNATMapping(nattype, externalIP, internalIP, port str
// If matches, let's skip it and continue the loop // If matches, let's skip it and continue the loop
if v.RuleType == nattype && if v.RuleType == nattype &&
v.GatewayNatRule.OriginalIP == externalIP && v.GatewayNatRule.OriginalIP == externalIP &&
v.GatewayNatRule.OriginalPort == port && v.GatewayNatRule.OriginalPort == externalPort &&
v.GatewayNatRule.Interface.HREF == uplink.HREF { v.GatewayNatRule.Interface.HREF == uplink.HREF {
log.Printf("[DEBUG] REMOVING %s Rule: %#v", v.RuleType, v.GatewayNatRule) log.Printf("[DEBUG] REMOVING %s Rule: %#v", v.RuleType, v.GatewayNatRule)
continue continue
...@@ -190,6 +194,10 @@ func (e *EdgeGateway) RemoveNATMapping(nattype, externalIP, internalIP, port str ...@@ -190,6 +194,10 @@ func (e *EdgeGateway) RemoveNATMapping(nattype, externalIP, internalIP, port str
} }
func (e *EdgeGateway) AddNATMapping(nattype, externalIP, internalIP, port string) (Task, error) { func (e *EdgeGateway) AddNATMapping(nattype, externalIP, internalIP, port string) (Task, error) {
return e.AddNATPortMapping(nattype, externalIP, port, internalIP, port)
}
func (e *EdgeGateway) AddNATPortMapping(nattype, externalIP, externalPort string, internalIP, internalPort string) (Task, error) {
// Find uplink interface // Find uplink interface
var uplink types.Reference var uplink types.Reference
for _, gi := range e.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface { for _, gi := range e.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface {
...@@ -218,8 +226,9 @@ func (e *EdgeGateway) AddNATMapping(nattype, externalIP, internalIP, port string ...@@ -218,8 +226,9 @@ func (e *EdgeGateway) AddNATMapping(nattype, externalIP, internalIP, port string
// If matches, let's skip it and continue the loop // If matches, let's skip it and continue the loop
if v.RuleType == nattype && if v.RuleType == nattype &&
v.GatewayNatRule.OriginalIP == externalIP && v.GatewayNatRule.OriginalIP == externalIP &&
v.GatewayNatRule.OriginalPort == port && v.GatewayNatRule.OriginalPort == externalPort &&
v.GatewayNatRule.TranslatedIP == internalIP && v.GatewayNatRule.TranslatedIP == internalIP &&
v.GatewayNatRule.TranslatedPort == internalPort &&
v.GatewayNatRule.Interface.HREF == uplink.HREF { v.GatewayNatRule.Interface.HREF == uplink.HREF {
continue continue
} }
...@@ -237,9 +246,9 @@ func (e *EdgeGateway) AddNATMapping(nattype, externalIP, internalIP, port string ...@@ -237,9 +246,9 @@ func (e *EdgeGateway) AddNATMapping(nattype, externalIP, internalIP, port string
HREF: uplink.HREF, HREF: uplink.HREF,
}, },
OriginalIP: externalIP, OriginalIP: externalIP,
OriginalPort: port, OriginalPort: externalPort,
TranslatedIP: internalIP, TranslatedIP: internalIP,
TranslatedPort: port, TranslatedPort: internalPort,
Protocol: "tcp", Protocol: "tcp",
}, },
} }
...@@ -623,3 +632,49 @@ func (e *EdgeGateway) Create1to1Mapping(internal, external, description string) ...@@ -623,3 +632,49 @@ func (e *EdgeGateway) Create1to1Mapping(internal, external, description string)
return *task, nil return *task, nil
} }
func (e *EdgeGateway) AddIpsecVPN(ipsecVPNConfig *types.EdgeGatewayServiceConfiguration) (Task, error) {
err := e.Refresh()
if err != nil {
fmt.Printf("error: %v\n", err)
}
output, err := xml.MarshalIndent(ipsecVPNConfig, " ", " ")
if err != nil {
fmt.Errorf("error marshaling ipsecVPNConfig compose: %s", err)
}
debug := os.Getenv("GOVCLOUDAIR_DEBUG")
if debug == "true" {
fmt.Printf("\n\nXML DEBUG: %s\n\n", string(output))
}
b := bytes.NewBufferString(xml.Header + string(output))
log.Printf("[DEBUG] ipsecVPN configuration: %s", b)
s, _ := url.ParseRequestURI(e.EdgeGateway.HREF)
s.Path += "/action/configureServices"
fmt.Println(s)
req := e.c.NewRequest(map[string]string{}, "POST", *s, b)
req.Header.Add("Content-Type", "application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml")
resp, err := checkResp(e.c.Http.Do(req))
if err != nil {
return Task{}, fmt.Errorf("error reconfiguring Edge Gateway: %s", err)
}
task := NewTask(e.c)
if err = decodeBody(resp, task.Task); err != nil {
return Task{}, fmt.Errorf("error decoding Task response: %s", err)
}
// The request was successful
return *task, nil
}
This diff is collapsed.
...@@ -55,6 +55,195 @@ func (v *VApp) Refresh() error { ...@@ -55,6 +55,195 @@ func (v *VApp) Refresh() error {
return nil return nil
} }
func (v *VApp) ComposeRawVApp(name string) error {
vcomp := &types.ComposeVAppParams{
Ovf: "http://schemas.dmtf.org/ovf/envelope/1",
Xsi: "http://www.w3.org/2001/XMLSchema-instance",
Xmlns: "http://www.vmware.com/vcloud/v1.5",
Deploy: false,
Name: name,
PowerOn: false,
}
output, err := xml.MarshalIndent(vcomp, " ", " ")
if err != nil {
return fmt.Errorf("error marshaling vapp compose: %s", err)
}
debug := os.Getenv("GOVCLOUDAIR_DEBUG")
if debug == "true" {
fmt.Printf("\n\nXML DEBUG: %s\n\n", string(output))
}
b := bytes.NewBufferString(xml.Header + string(output))
s := v.c.VCDVDCHREF
s.Path += "/action/composeVApp"
req := v.c.NewRequest(map[string]string{}, "POST", s, b)
req.Header.Add("Content-Type", "application/vnd.vmware.vcloud.composeVAppParams+xml")
resp, err := checkResp(v.c.Http.Do(req))
if err != nil {
return fmt.Errorf("error instantiating a new vApp: %s", err)
}
if err = decodeBody(resp, v.VApp); err != nil {
return fmt.Errorf("error decoding vApp response: %s", err)
}
task := NewTask(v.c)
for _, t := range v.VApp.Tasks.Task {
task.Task = t
err = task.WaitTaskCompletion()
if err != nil {
return fmt.Errorf("Error performing task: %#v", err)
}
}
return nil
}
func (v *VApp) AddVM(orgvdcnetwork OrgVDCNetwork, vapptemplate VAppTemplate, name string) error {
vcomp := &types.ReComposeVAppParams{
Ovf: "http://schemas.dmtf.org/ovf/envelope/1",
Xsi: "http://www.w3.org/2001/XMLSchema-instance",
Xmlns: "http://www.vmware.com/vcloud/v1.5",
Deploy: false,
Name: v.VApp.Name,
PowerOn: false,
Description: v.VApp.Description,
SourcedItem: &types.SourcedCompositionItemParam{
Source: &types.Reference{
HREF: vapptemplate.VAppTemplate.Children.VM[0].HREF,
Name: name,
},
InstantiationParams: &types.InstantiationParams{
NetworkConnectionSection: &types.NetworkConnectionSection{
Type: vapptemplate.VAppTemplate.Children.VM[0].NetworkConnectionSection.Type,
HREF: vapptemplate.VAppTemplate.Children.VM[0].NetworkConnectionSection.HREF,
Info: "Network config for sourced item",
PrimaryNetworkConnectionIndex: vapptemplate.VAppTemplate.Children.VM[0].NetworkConnectionSection.PrimaryNetworkConnectionIndex,
NetworkConnection: &types.NetworkConnection{
Network: orgvdcnetwork.OrgVDCNetwork.Name,
NetworkConnectionIndex: vapptemplate.VAppTemplate.Children.VM[0].NetworkConnectionSection.NetworkConnection.NetworkConnectionIndex,
IsConnected: true,
IPAddressAllocationMode: "POOL",
},
},
},
NetworkAssignment: &types.NetworkAssignment{
InnerNetwork: orgvdcnetwork.OrgVDCNetwork.Name,
ContainerNetwork: orgvdcnetwork.OrgVDCNetwork.Name,
},
},
}
output, _ := xml.MarshalIndent(vcomp, " ", " ")
s, _ := url.ParseRequestURI(v.VApp.HREF)
s.Path += "/action/recomposeVApp"
fmt.Println(s)
fmt.Println(string(output))
b := bytes.NewBufferString(xml.Header + string(output))
req := v.c.NewRequest(map[string]string{}, "POST", *s, b)
req.Header.Add("Content-Type", "application/vnd.vmware.vcloud.recomposeVAppParams+xml")
task := NewTask(v.c)
v.Refresh()
if v.VApp.Tasks != nil {
fmt.Println("AYE")
for _, t := range v.VApp.Tasks.Task {
task.Task = t
err := task.WaitTaskCompletion()
if err != nil {
return fmt.Errorf("Error performing task: %#v", err)
}
}
} else {
fmt.Println("NO")
}
resp, err := checkResp(v.c.Http.Do(req))
if err != nil {
return fmt.Errorf("error instantiating a new vApp: %s", err)
}
task = NewTask(v.c)
if err = decodeBody(resp, task.Task); err != nil {
return fmt.Errorf("error decoding task response: %s", err)
}
err = task.WaitTaskCompletion()
if err != nil {
return fmt.Errorf("Error performing task: %#v", err)
}
return nil
}
func (v *VApp) RemoveVM(vm VM) error {
task := NewTask(v.c)
for _, t := range v.VApp.Tasks.Task {
task.Task = t
err := task.WaitTaskCompletion()
if err != nil {
return fmt.Errorf("Error performing task: %#v", err)
}
}
vcomp := &types.ReComposeVAppParams{
Ovf: "http://schemas.dmtf.org/ovf/envelope/1",
Xsi: "http://www.w3.org/2001/XMLSchema-instance",
Xmlns: "http://www.vmware.com/vcloud/v1.5",
DeleteItem: &types.DeleteItem{
HREF: vm.VM.HREF,
},
}
output, _ := xml.MarshalIndent(vcomp, " ", " ")
s, _ := url.ParseRequestURI(v.VApp.HREF)
s.Path += "/action/recomposeVApp"
fmt.Println(s)
fmt.Println(string(output))
b := bytes.NewBufferString(xml.Header + string(output))
req := v.c.NewRequest(map[string]string{}, "POST", *s, b)
req.Header.Add("Content-Type", "application/vnd.vmware.vcloud.recomposeVAppParams+xml")
resp, err := checkResp(v.c.Http.Do(req))
if err != nil {
return fmt.Errorf("error instantiating a new vApp: %s", err)
}
task = NewTask(v.c)
if err = decodeBody(resp, task.Task); err != nil {
return fmt.Errorf("error decoding task response: %s", err)
}
err = task.WaitTaskCompletion()
if err != nil {
return fmt.Errorf("Error performing task: %#v", err)
}
return nil
}
func (v *VApp) ComposeVApp(orgvdcnetwork OrgVDCNetwork, vapptemplate VAppTemplate, name string, description string) (Task, error) { func (v *VApp) ComposeVApp(orgvdcnetwork OrgVDCNetwork, vapptemplate VAppTemplate, name string, description string) (Task, error) {
if vapptemplate.VAppTemplate.Children == nil || orgvdcnetwork.OrgVDCNetwork == nil { if vapptemplate.VAppTemplate.Children == nil || orgvdcnetwork.OrgVDCNetwork == nil {
...@@ -396,7 +585,10 @@ func (v *VApp) Delete() (Task, error) { ...@@ -396,7 +585,10 @@ func (v *VApp) Delete() (Task, error) {
} }
func (v *VApp) RunCustomizationScript(computername, script string) (Task, error) { func (v *VApp) RunCustomizationScript(computername, script string) (Task, error) {
return v.Customize(computername, script, false)
}
func (v *VApp) Customize(computername, script string, changeSid bool) (Task, error) {
err := v.Refresh() err := v.Refresh()
if err != nil { if err != nil {
return Task{}, fmt.Errorf("error refreshing vapp before running customization: %v", err) return Task{}, fmt.Errorf("error refreshing vapp before running customization: %v", err)
...@@ -418,6 +610,7 @@ func (v *VApp) RunCustomizationScript(computername, script string) (Task, error) ...@@ -418,6 +610,7 @@ func (v *VApp) RunCustomizationScript(computername, script string) (Task, error)
Enabled: true, Enabled: true,
ComputerName: computername, ComputerName: computername,
CustomizationScript: script, CustomizationScript: script,
ChangeSid: false,
} }
output, err := xml.MarshalIndent(vu, " ", " ") output, err := xml.MarshalIndent(vu, " ", " ")
......
...@@ -67,7 +67,7 @@ func (v *Vdc) Refresh() error { ...@@ -67,7 +67,7 @@ func (v *Vdc) Refresh() error {
} }
v.Vdc = unmarshalledVdc v.Vdc = unmarshalledVdc
// The request was successful // The request was successful
return nil return nil
} }
...@@ -217,7 +217,7 @@ func (v *Vdc) FindVAppByName(vapp string) (VApp, error) { ...@@ -217,7 +217,7 @@ func (v *Vdc) FindVAppByName(vapp string) (VApp, error) {
newvapp := NewVApp(v.c) newvapp := NewVApp(v.c)
if err = decodeBody(resp, newvapp.VApp); err != nil { if err = decodeBody(resp, newvapp.VApp); err != nil {
return VApp{}, fmt.Errorf("error decoding vApp response: %s", err) return VApp{}, fmt.Errorf("error decoding vApp response: %s", err.Error())
} }
return *newvapp, nil return *newvapp, nil
...@@ -228,6 +228,48 @@ func (v *Vdc) FindVAppByName(vapp string) (VApp, error) { ...@@ -228,6 +228,48 @@ func (v *Vdc) FindVAppByName(vapp string) (VApp, error) {
return VApp{}, fmt.Errorf("can't find vApp: %s", vapp) return VApp{}, fmt.Errorf("can't find vApp: %s", vapp)
} }
func (v *Vdc) FindVMByName(vapp VApp, vm string) (VM, error) {
err := v.Refresh()
if err != nil {
return VM{}, fmt.Errorf("error refreshing vdc: %s", err)
}
for _, child := range vapp.VApp.Children.VM {
if child.Name == vm {
u, err := url.ParseRequestURI(child.HREF)
if err != nil {
return VM{}, fmt.Errorf("error decoding vdc response: %s", err)
}
// Querying the VApp
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
resp, err := checkResp(v.c.Http.Do(req))
if err != nil {
return VM{}, fmt.Errorf("error retrieving vm: %s", err)
}
newvm := NewVM(v.c)
//body, err := ioutil.ReadAll(resp.Body)
//fmt.Println(string(body))
if err = decodeBody(resp, newvm.VM); err != nil {
return VM{}, fmt.Errorf("error decoding vm response: %s", err.Error())
}
return *newvm, nil
}
}
return VM{}, fmt.Errorf("can't find vm: %s", vm)
}
func (v *Vdc) FindVAppByID(vappid string) (VApp, error) { func (v *Vdc) FindVAppByID(vappid string) (VApp, error) {
// Horrible hack to fetch a vapp with its id. // Horrible hack to fetch a vapp with its id.
......
...@@ -2906,16 +2906,16 @@ ...@@ -2906,16 +2906,16 @@
"revisionTime": "2016-09-28T01:52:44Z" "revisionTime": "2016-09-28T01:52:44Z"
}, },
{ {
"checksumSHA1": "y4ihcZrjJdyQDnsKLelo9/1MjqE=", "checksumSHA1": "q+FWbxP3r4GRzEx+zZpmjhZ5b5Y=",
"path": "github.com/ukcloud/govcloudair", "path": "github.com/ukcloud/govcloudair",
"revision": "9076b4221ebf430944c716c798e904e00cbaa89d", "revision": "993d72d0f08369c36ef0d4220edff65bae450a05",
"revisionTime": "2017-01-31T00:00:54Z" "revisionTime": "2017-03-28T11:27:18Z"
}, },
{ {
"checksumSHA1": "CridJfrpcrjMdXnf7PbqA/+7wuY=", "checksumSHA1": "8FHandxT6XIwsawRe0eNupivqho=",
"path": "github.com/ukcloud/govcloudair/types/v56", "path": "github.com/ukcloud/govcloudair/types/v56",
"revision": "9076b4221ebf430944c716c798e904e00cbaa89d", "revision": "993d72d0f08369c36ef0d4220edff65bae450a05",
"revisionTime": "2017-01-31T00:00:54Z" "revisionTime": "2017-03-28T11:27:18Z"
}, },
{ {
"checksumSHA1": "CdE9OUEGLn2pAv1UMuM5rSlaUpM=", "checksumSHA1": "CdE9OUEGLn2pAv1UMuM5rSlaUpM=",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment