terraform/vendor/github.com/ukcloud/govcloudair/vdc.go

323 lines
7.7 KiB
Go

/*
* Copyright 2014 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
*/
package govcloudair
import (
"fmt"
"net/url"
"strings"
types "github.com/ukcloud/govcloudair/types/v56"
)
type Vdc struct {
Vdc *types.Vdc
c *Client
}
func NewVdc(c *Client) *Vdc {
return &Vdc{
Vdc: new(types.Vdc),
c: c,
}
}
func (c *Client) retrieveVDC() (Vdc, error) {
req := c.NewRequest(map[string]string{}, "GET", c.VCDVDCHREF, nil)
resp, err := checkResp(c.Http.Do(req))
if err != nil {
return Vdc{}, fmt.Errorf("error retreiving vdc: %s", err)
}
vdc := NewVdc(c)
if err = decodeBody(resp, vdc.Vdc); err != nil {
return Vdc{}, fmt.Errorf("error decoding vdc response: %s", err)
}
// The request was successful
return *vdc, nil
}
func (v *Vdc) Refresh() error {
if v.Vdc.HREF == "" {
return fmt.Errorf("cannot refresh, Object is empty")
}
u, _ := url.ParseRequestURI(v.Vdc.HREF)
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
resp, err := checkResp(v.c.Http.Do(req))
if err != nil {
return fmt.Errorf("error retreiving Edge Gateway: %s", err)
}
// Empty struct before a new unmarshal, otherwise we end up with duplicate
// elements in slices.
unmarshalledVdc := &types.Vdc{}
if err = decodeBody(resp, unmarshalledVdc); err != nil {
return fmt.Errorf("error decoding vdc response: %s", err)
}
v.Vdc = unmarshalledVdc
// The request was successful
return nil
}
func (v *Vdc) FindVDCNetwork(network string) (OrgVDCNetwork, error) {
for _, an := range v.Vdc.AvailableNetworks {
for _, n := range an.Network {
if n.Name == network {
u, err := url.ParseRequestURI(n.HREF)
if err != nil {
return OrgVDCNetwork{}, fmt.Errorf("error decoding vdc response: %s", err)
}
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
resp, err := checkResp(v.c.Http.Do(req))
if err != nil {
return OrgVDCNetwork{}, fmt.Errorf("error retreiving orgvdcnetwork: %s", err)
}
orgnet := NewOrgVDCNetwork(v.c)
if err = decodeBody(resp, orgnet.OrgVDCNetwork); err != nil {
return OrgVDCNetwork{}, fmt.Errorf("error decoding orgvdcnetwork response: %s", err)
}
// The request was successful
return *orgnet, nil
}
}
}
return OrgVDCNetwork{}, fmt.Errorf("can't find VDC Network: %s", network)
}
// Doesn't work with vCloud API 5.5, only vCloud Air
func (v *Vdc) GetVDCOrg() (Org, error) {
for _, av := range v.Vdc.Link {
if av.Rel == "up" && av.Type == "application/vnd.vmware.vcloud.org+xml" {
u, err := url.ParseRequestURI(av.HREF)
if err != nil {
return Org{}, fmt.Errorf("error decoding vdc response: %s", err)
}
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
resp, err := checkResp(v.c.Http.Do(req))
if err != nil {
return Org{}, fmt.Errorf("error retreiving org: %s", err)
}
org := NewOrg(v.c)
if err = decodeBody(resp, org.Org); err != nil {
return Org{}, fmt.Errorf("error decoding org response: %s", err)
}
// The request was successful
return *org, nil
}
}
return Org{}, fmt.Errorf("can't find VDC Org")
}
func (v *Vdc) FindEdgeGateway(edgegateway string) (EdgeGateway, error) {
for _, av := range v.Vdc.Link {
if av.Rel == "edgeGateways" && av.Type == "application/vnd.vmware.vcloud.query.records+xml" {
u, err := url.ParseRequestURI(av.HREF)
if err != nil {
return EdgeGateway{}, fmt.Errorf("error decoding vdc response: %s", err)
}
// Querying the Result list
req := v.c.NewRequest(map[string]string{}, "GET", *u, nil)
resp, err := checkResp(v.c.Http.Do(req))
if err != nil {
return EdgeGateway{}, fmt.Errorf("error retrieving edge gateway records: %s", err)
}
query := new(types.QueryResultEdgeGatewayRecordsType)
if err = decodeBody(resp, query); err != nil {
return EdgeGateway{}, fmt.Errorf("error decoding edge gateway query response: %s", err)
}
u, err = url.ParseRequestURI(query.EdgeGatewayRecord.HREF)
if err != nil {
return EdgeGateway{}, fmt.Errorf("error decoding edge gateway query response: %s", err)
}
// Querying the Result list
req = v.c.NewRequest(map[string]string{}, "GET", *u, nil)
resp, err = checkResp(v.c.Http.Do(req))
if err != nil {
return EdgeGateway{}, fmt.Errorf("error retrieving edge gateway: %s", err)
}
edge := NewEdgeGateway(v.c)
if err = decodeBody(resp, edge.EdgeGateway); err != nil {
return EdgeGateway{}, fmt.Errorf("error decoding edge gateway response: %s", err)
}
return *edge, nil
}
}
return EdgeGateway{}, fmt.Errorf("can't find Edge Gateway")
}
func (v *Vdc) FindVAppByName(vapp string) (VApp, error) {
err := v.Refresh()
if err != nil {
return VApp{}, fmt.Errorf("error refreshing vdc: %s", err)
}
for _, resents := range v.Vdc.ResourceEntities {
for _, resent := range resents.ResourceEntity {
if resent.Name == vapp && resent.Type == "application/vnd.vmware.vcloud.vApp+xml" {
u, err := url.ParseRequestURI(resent.HREF)
if err != nil {
return VApp{}, 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 VApp{}, fmt.Errorf("error retrieving vApp: %s", err)
}
newvapp := NewVApp(v.c)
if err = decodeBody(resp, newvapp.VApp); err != nil {
return VApp{}, fmt.Errorf("error decoding vApp response: %s", err.Error())
}
return *newvapp, nil
}
}
}
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) {
// Horrible hack to fetch a vapp with its id.
// urn:vcloud:vapp:00000000-0000-0000-0000-000000000000
err := v.Refresh()
if err != nil {
return VApp{}, fmt.Errorf("error refreshing vdc: %s", err)
}
urnslice := strings.SplitAfter(vappid, ":")
urnid := urnslice[len(urnslice)-1]
for _, resents := range v.Vdc.ResourceEntities {
for _, resent := range resents.ResourceEntity {
hrefslice := strings.SplitAfter(resent.HREF, "/")
hrefslice = strings.SplitAfter(hrefslice[len(hrefslice)-1], "-")
res := strings.Join(hrefslice[1:], "")
if res == urnid && resent.Type == "application/vnd.vmware.vcloud.vApp+xml" {
u, err := url.ParseRequestURI(resent.HREF)
if err != nil {
return VApp{}, 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 VApp{}, fmt.Errorf("error retrieving vApp: %s", err)
}
newvapp := NewVApp(v.c)
if err = decodeBody(resp, newvapp.VApp); err != nil {
return VApp{}, fmt.Errorf("error decoding vApp response: %s", err)
}
return *newvapp, nil
}
}
}
return VApp{}, fmt.Errorf("can't find vApp")
}