Update Lego (Gandi API v5, cloudxns, ...)
This commit is contained in:
parent
dd873fbeee
commit
7d3dd5a0e4
43 changed files with 4112 additions and 1238 deletions
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
vendor/github.com/xenolf/lego/providers/dns/cloudxns/cloudxns.go eol=crlf
|
||||||
|
|
7
Gopkg.lock
generated
7
Gopkg.lock
generated
|
@ -525,7 +525,8 @@
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/exoscale/egoscale"
|
name = "github.com/exoscale/egoscale"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "325740036187ddae3a5b74be00fbbc70011c4d96"
|
revision = "e4fedc381fbddb7fef4d7060388a726c6de37c88"
|
||||||
|
version = "v0.9.7"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/fatih/color"
|
name = "github.com/fatih/color"
|
||||||
|
@ -1182,6 +1183,7 @@
|
||||||
"providers/dns/auroradns",
|
"providers/dns/auroradns",
|
||||||
"providers/dns/azure",
|
"providers/dns/azure",
|
||||||
"providers/dns/cloudflare",
|
"providers/dns/cloudflare",
|
||||||
|
"providers/dns/cloudxns",
|
||||||
"providers/dns/digitalocean",
|
"providers/dns/digitalocean",
|
||||||
"providers/dns/dnsimple",
|
"providers/dns/dnsimple",
|
||||||
"providers/dns/dnsmadeeasy",
|
"providers/dns/dnsmadeeasy",
|
||||||
|
@ -1189,6 +1191,7 @@
|
||||||
"providers/dns/dyn",
|
"providers/dns/dyn",
|
||||||
"providers/dns/exoscale",
|
"providers/dns/exoscale",
|
||||||
"providers/dns/gandi",
|
"providers/dns/gandi",
|
||||||
|
"providers/dns/gandiv5",
|
||||||
"providers/dns/godaddy",
|
"providers/dns/godaddy",
|
||||||
"providers/dns/googlecloud",
|
"providers/dns/googlecloud",
|
||||||
"providers/dns/linode",
|
"providers/dns/linode",
|
||||||
|
@ -1202,7 +1205,7 @@
|
||||||
"providers/dns/route53",
|
"providers/dns/route53",
|
||||||
"providers/dns/vultr"
|
"providers/dns/vultr"
|
||||||
]
|
]
|
||||||
revision = "b929aa5aab5ad2e197bb3d74ef99fac61bfa47bc"
|
revision = "06a8e7c475c03ef8d4773284ac63357d2810601b"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
|
|
@ -113,7 +113,7 @@ entryPoint = "https"
|
||||||
# Required
|
# Required
|
||||||
#
|
#
|
||||||
entryPoint = "http"
|
entryPoint = "http"
|
||||||
|
|
||||||
# Use a DNS-01 acme challenge rather than TLS-SNI-01 challenge
|
# Use a DNS-01 acme challenge rather than TLS-SNI-01 challenge
|
||||||
#
|
#
|
||||||
# Optional
|
# Optional
|
||||||
|
@ -272,7 +272,7 @@ Use `DNS-01` challenge to generate/renew ACME certificates.
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `provider`
|
#### `provider`
|
||||||
|
|
||||||
Select the provider that matches the DNS domain that will host the challenge TXT record, and provide environment variables to enable setting it:
|
Select the provider that matches the DNS domain that will host the challenge TXT record, and provide environment variables to enable setting it:
|
||||||
|
|
||||||
|
@ -281,6 +281,7 @@ Select the provider that matches the DNS domain that will host the challenge TXT
|
||||||
| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` |
|
| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` |
|
||||||
| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP` |
|
| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP` |
|
||||||
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CLOUDFLARE_EMAIL`, `CLOUDFLARE_API_KEY` - The Cloudflare `Global API Key` needs to be used and not the `Origin CA Key` |
|
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CLOUDFLARE_EMAIL`, `CLOUDFLARE_API_KEY` - The Cloudflare `Global API Key` needs to be used and not the `Origin CA Key` |
|
||||||
|
| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` |
|
||||||
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` |
|
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` |
|
||||||
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` |
|
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` |
|
||||||
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` |
|
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` |
|
||||||
|
@ -288,6 +289,7 @@ Select the provider that matches the DNS domain that will host the challenge TXT
|
||||||
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` |
|
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` |
|
||||||
| [Exoscale](https://www.exoscale.ch) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` |
|
| [Exoscale](https://www.exoscale.ch) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` |
|
||||||
| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` |
|
| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` |
|
||||||
|
| [Gandi V5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` |
|
||||||
| [GoDaddy](https://godaddy.com/domains) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` |
|
| [GoDaddy](https://godaddy.com/domains) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` |
|
||||||
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, `GCE_SERVICE_ACCOUNT_FILE` |
|
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, `GCE_SERVICE_ACCOUNT_FILE` |
|
||||||
| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` |
|
| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` |
|
||||||
|
@ -330,7 +332,7 @@ This will request a certificate from Let's Encrypt during the first TLS handshak
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
TLS handshakes will be slow when requesting a hostname certificate for the first time, this can lead to DoS attacks.
|
TLS handshakes will be slow when requesting a hostname certificate for the first time, this can lead to DoS attacks.
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
Take note that Let's Encrypt have [rate limiting](https://letsencrypt.org/docs/rate-limits).
|
Take note that Let's Encrypt have [rate limiting](https://letsencrypt.org/docs/rate-limits).
|
||||||
|
|
||||||
|
|
98
vendor/github.com/exoscale/egoscale/accounts.go
generated
vendored
Normal file
98
vendor/github.com/exoscale/egoscale/accounts.go
generated
vendored
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
const (
|
||||||
|
// UserAccount represents a User
|
||||||
|
UserAccount = iota
|
||||||
|
// AdminAccount represents an Admin
|
||||||
|
AdminAccount
|
||||||
|
// DomainAdminAccount represents a Domain Admin
|
||||||
|
DomainAdminAccount
|
||||||
|
)
|
||||||
|
|
||||||
|
// AccountType represents the type of an Account
|
||||||
|
//
|
||||||
|
// http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/4.8/accounts.html#accounts-users-and-domains
|
||||||
|
type AccountType int64
|
||||||
|
|
||||||
|
// Account provides the detailed account information
|
||||||
|
type Account struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
AccountType AccountType `json:"accounttype,omitempty"`
|
||||||
|
AccountDetails string `json:"accountdetails,omitempty"`
|
||||||
|
CPUAvailable string `json:"cpuavailable,omitempty"`
|
||||||
|
CPULimit string `json:"cpulimit,omitempty"`
|
||||||
|
CPUTotal int64 `json:"cputotal,omitempty"`
|
||||||
|
DefaultZoneID string `json:"defaultzoneid,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
EIPLimit string `json:"eiplimit,omitempty"`
|
||||||
|
Groups []string `json:"groups,omitempty"`
|
||||||
|
IPAvailable string `json:"ipavailable,omitempty"`
|
||||||
|
IPLimit string `json:"iplimit,omitempty"`
|
||||||
|
IPTotal int64 `json:"iptotal,omitempty"`
|
||||||
|
IsDefault bool `json:"isdefault,omitempty"`
|
||||||
|
MemoryAvailable string `json:"memoryavailable,omitempty"`
|
||||||
|
MemoryLimit string `json:"memorylimit,omitempty"`
|
||||||
|
MemoryTotal int64 `json:"memorytotal,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkAvailable string `json:"networkavailable,omitempty"`
|
||||||
|
NetworkDomain string `json:"networkdomain,omitempty"`
|
||||||
|
NetworkLimit string `json:"networklimit,omitempty"`
|
||||||
|
NetworkTotal int16 `json:"networktotal,omitempty"`
|
||||||
|
PrimaryStorageAvailable string `json:"primarystorageavailable,omitempty"`
|
||||||
|
PrimaryStorageLimit string `json:"primarystoragelimit,omitempty"`
|
||||||
|
PrimaryStorageTotal int64 `json:"primarystoragetotal,omitempty"`
|
||||||
|
ProjectAvailable string `json:"projectavailable,omitempty"`
|
||||||
|
ProjectLimit string `json:"projectlimit,omitempty"`
|
||||||
|
ProjectTotal int64 `json:"projecttotal,omitempty"`
|
||||||
|
SecondaryStorageAvailable string `json:"secondarystorageavailable,omitempty"`
|
||||||
|
SecondaryStorageLimit string `json:"secondarystoragelimit,omitempty"`
|
||||||
|
SecondaryStorageTotal int64 `json:"secondarystoragetotal,omitempty"`
|
||||||
|
SnapshotAvailable string `json:"snapshotavailable,omitempty"`
|
||||||
|
SnapshotLimit string `json:"snapshotlimit,omitempty"`
|
||||||
|
SnapshotTotal int64 `json:"snapshottotal,omitempty"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
TemplateAvailable string `json:"templateavailable,omitempty"`
|
||||||
|
TemplateLimit string `json:"templatelimit,omitempty"`
|
||||||
|
TemplateTotal int64 `json:"templatetotal,omitempty"`
|
||||||
|
VMAvailable string `json:"vmavailable,omitempty"`
|
||||||
|
VMLimit string `json:"vmlimit,omitempty"`
|
||||||
|
VMTotal int64 `json:"vmtotal,omitempty"`
|
||||||
|
VolumeAvailable string `json:"volumeavailable,omitempty"`
|
||||||
|
VolumeLimit string `json:"volumelimit,omitempty"`
|
||||||
|
VolumeTotal int64 `json:"volumetotal,omitempty"`
|
||||||
|
VPCAvailable string `json:"vpcavailable,omitempty"`
|
||||||
|
VPCLimit string `json:"vpclimit,omitempty"`
|
||||||
|
VPCTotal int64 `json:"vpctotal,omitempty"`
|
||||||
|
User []User `json:"user,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAccounts represents a query to display the accounts
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listAccounts.html
|
||||||
|
type ListAccounts struct {
|
||||||
|
AccountType int64 `json:"accounttype,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsCleanUpRequired bool `json:"iscleanuprequired,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListAccounts) name() string {
|
||||||
|
return "listAccounts"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListAccounts) response() interface{} {
|
||||||
|
return new(ListAccountsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAccountsResponse represents a list of accounts
|
||||||
|
type ListAccountsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
Account []Account `json:"account"`
|
||||||
|
}
|
148
vendor/github.com/exoscale/egoscale/addresses.go
generated
vendored
Normal file
148
vendor/github.com/exoscale/egoscale/addresses.go
generated
vendored
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
import "net"
|
||||||
|
|
||||||
|
// IPAddress represents an IP Address
|
||||||
|
type IPAddress struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
AllocatedAt string `json:"allocated,omitempty"`
|
||||||
|
AssociatedNetworkID string `json:"associatednetworkid,omitempty"`
|
||||||
|
AssociatedNetworkName string `json:"associatednetworkname,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
DomainName string `json:"domainname,omitempty"`
|
||||||
|
ForDisplay bool `json:"fordisplay,omitempty"`
|
||||||
|
ForVirtualNetwork bool `json:"forvirtualnetwork,omitempty"`
|
||||||
|
IPAddress net.IP `json:"ipaddress"`
|
||||||
|
IsElastic bool `json:"iselastic,omitempty"`
|
||||||
|
IsPortable bool `json:"isportable,omitempty"`
|
||||||
|
IsSourceNat bool `json:"issourcenat,omitempty"`
|
||||||
|
IsSystem bool `json:"issystem,omitempty"`
|
||||||
|
NetworkID string `json:"networkid,omitempty"`
|
||||||
|
PhysicalNetworkID string `json:"physicalnetworkid,omitempty"`
|
||||||
|
Project string `json:"project,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
Purpose string `json:"purpose,omitempty"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
VirtualMachineDisplayName string `json:"virtualmachinedisplayname,omitempty"`
|
||||||
|
VirtualMachineID string `json:"virtualmachineid,omitempty"`
|
||||||
|
VirtualMachineName string `json:"virtualmachineName,omitempty"`
|
||||||
|
VlanID string `json:"vlanid,omitempty"`
|
||||||
|
VlanName string `json:"vlanname,omitempty"`
|
||||||
|
VMIPAddress net.IP `json:"vmipaddress,omitempty"`
|
||||||
|
VpcID string `json:"vpcid,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
ZoneName string `json:"zonename,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
JobID string `json:"jobid,omitempty"`
|
||||||
|
JobStatus JobStatusType `json:"jobstatus,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceType returns the type of the resource
|
||||||
|
func (*IPAddress) ResourceType() string {
|
||||||
|
return "PublicIpAddress"
|
||||||
|
}
|
||||||
|
|
||||||
|
// AssociateIPAddress (Async) represents the IP creation
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/associateIpAddress.html
|
||||||
|
type AssociateIPAddress struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ForDisplay bool `json:"fordisplay,omitempty"`
|
||||||
|
IsPortable bool `json:"isportable,omitempty"`
|
||||||
|
NetworkdID string `json:"networkid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
RegionID string `json:"regionid,omitempty"`
|
||||||
|
VpcID string `json:"vpcid,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*AssociateIPAddress) name() string {
|
||||||
|
return "associateIpAddress"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*AssociateIPAddress) asyncResponse() interface{} {
|
||||||
|
return new(AssociateIPAddressResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AssociateIPAddressResponse represents the response to the creation of an IPAddress
|
||||||
|
type AssociateIPAddressResponse struct {
|
||||||
|
IPAddress IPAddress `json:"ipaddress"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisassociateIPAddress (Async) represents the IP deletion
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/disassociateIpAddress.html
|
||||||
|
type DisassociateIPAddress struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DisassociateIPAddress) name() string {
|
||||||
|
return "disassociateIpAddress"
|
||||||
|
}
|
||||||
|
func (*DisassociateIPAddress) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateIPAddress (Async) represents the IP modification
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/updateIpAddress.html
|
||||||
|
type UpdateIPAddress struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
CustomID string `json:"customid,omitempty"` // root only
|
||||||
|
ForDisplay bool `json:"fordisplay,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateIPAddress) name() string {
|
||||||
|
return "updateIpAddress"
|
||||||
|
}
|
||||||
|
func (*UpdateIPAddress) asyncResponse() interface{} {
|
||||||
|
return new(UpdateIPAddressResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateIPAddressResponse represents the modified IP Address
|
||||||
|
type UpdateIPAddressResponse AssociateIPAddressResponse
|
||||||
|
|
||||||
|
// ListPublicIPAddresses represents a search for public IP addresses
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listPublicIpAddresses.html
|
||||||
|
type ListPublicIPAddresses struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
AllocatedOnly bool `json:"allocatedonly,omitempty"`
|
||||||
|
AllocatedNetworkID string `json:"allocatednetworkid,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ForDisplay bool `json:"fordisplay,omitempty"`
|
||||||
|
ForLoadBalancing bool `json:"forloadbalancing,omitempty"`
|
||||||
|
ForVirtualNetwork string `json:"forvirtualnetwork,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IPAddress net.IP `json:"ipaddress,omitempty"`
|
||||||
|
IsElastic bool `json:"iselastic,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
IsSourceNat bool `json:"issourcenat,omitempty"`
|
||||||
|
IsStaticNat bool `json:"isstaticnat,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omiempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
PhysicalNetworkID string `json:"physicalnetworkid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
VlanID string `json:"vlanid,omitempty"`
|
||||||
|
VpcID string `json:"vpcid,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListPublicIPAddresses) name() string {
|
||||||
|
return "listPublicIpAddresses"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListPublicIPAddresses) response() interface{} {
|
||||||
|
return new(ListPublicIPAddressesResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPublicIPAddressesResponse represents a list of public IP addresses
|
||||||
|
type ListPublicIPAddressesResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
PublicIPAddress []IPAddress `json:"publicipaddress"`
|
||||||
|
}
|
176
vendor/github.com/exoscale/egoscale/affinity_groups.go
generated
vendored
Normal file
176
vendor/github.com/exoscale/egoscale/affinity_groups.go
generated
vendored
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AffinityGroup represents an (anti-)affinity group
|
||||||
|
type AffinityGroup struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
VirtualMachineIDs []string `json:"virtualmachineIDs,omitempty"` // *I*ds is not a typo
|
||||||
|
}
|
||||||
|
|
||||||
|
// AffinityGroupType represent an affinity group type
|
||||||
|
type AffinityGroupType struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateAffinityGroup (Async) represents a new (anti-)affinity group
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createAffinityGroup.html
|
||||||
|
type CreateAffinityGroup struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateAffinityGroup) name() string {
|
||||||
|
return "createAffinityGroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateAffinityGroup) asyncResponse() interface{} {
|
||||||
|
return new(CreateAffinityGroupResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateAffinityGroupResponse represents the response of the creation of an (anti-)affinity group
|
||||||
|
type CreateAffinityGroupResponse struct {
|
||||||
|
AffinityGroup AffinityGroup `json:"affinitygroup"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateVMAffinityGroup (Async) represents a modification of a (anti-)affinity group
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/updateVMAffinityGroup.html
|
||||||
|
type UpdateVMAffinityGroup struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
AffinityGroupIDs []string `json:"affinitygroupids,omitempty"` // mutually exclusive with names
|
||||||
|
AffinityGroupNames []string `json:"affinitygroupnames,omitempty"` // mutually exclusive with ids
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateVMAffinityGroup) name() string {
|
||||||
|
return "updateVMAffinityGroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateVMAffinityGroup) asyncResponse() interface{} {
|
||||||
|
return new(UpdateVMAffinityGroupResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req *UpdateVMAffinityGroup) onBeforeSend(params *url.Values) error {
|
||||||
|
// Either AffinityGroupIDs or AffinityGroupNames must be set
|
||||||
|
if len(req.AffinityGroupIDs) == 0 && len(req.AffinityGroupNames) == 0 {
|
||||||
|
params.Set("affinitygroupids", "")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateVMAffinityGroupResponse represents the new VM
|
||||||
|
type UpdateVMAffinityGroupResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// DeleteAffinityGroup (Async) represents an (anti-)affinity group to be deleted
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteAffinityGroup.html
|
||||||
|
type DeleteAffinityGroup struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteAffinityGroup) name() string {
|
||||||
|
return "deleteAffinityGroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteAffinityGroup) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAffinityGroups represents an (anti-)affinity groups search
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listAffinityGroups.html
|
||||||
|
type ListAffinityGroups struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
VirtualMachineID string `json:"virtualmachineid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListAffinityGroups) name() string {
|
||||||
|
return "listAffinityGroups"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListAffinityGroups) response() interface{} {
|
||||||
|
return new(ListAffinityGroupsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAffinityGroupTypes represents an (anti-)affinity groups search
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listAffinityGroupTypes.html
|
||||||
|
type ListAffinityGroupTypes struct {
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListAffinityGroupTypes) name() string {
|
||||||
|
return "listAffinityGroupTypes"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListAffinityGroupTypes) response() interface{} {
|
||||||
|
return new(ListAffinityGroupTypesResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAffinityGroupsResponse represents a list of (anti-)affinity groups
|
||||||
|
type ListAffinityGroupsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
AffinityGroup []AffinityGroup `json:"affinitygroup"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAffinityGroupTypesResponse represents a list of (anti-)affinity group types
|
||||||
|
type ListAffinityGroupTypesResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
AffinityGroupType []AffinityGroupType `json:"affinitygrouptype"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy methods
|
||||||
|
|
||||||
|
// CreateAffinityGroup creates a group
|
||||||
|
//
|
||||||
|
// Deprecated: Use the API directly
|
||||||
|
func (exo *Client) CreateAffinityGroup(name string, async AsyncInfo) (*AffinityGroup, error) {
|
||||||
|
req := &CreateAffinityGroup{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
resp, err := exo.AsyncRequest(req, async)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ag := resp.(*CreateAffinityGroupResponse).AffinityGroup
|
||||||
|
return &ag, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteAffinityGroup deletes a group
|
||||||
|
//
|
||||||
|
// Deprecated: Use the API directly
|
||||||
|
func (exo *Client) DeleteAffinityGroup(name string, async AsyncInfo) error {
|
||||||
|
req := &DeleteAffinityGroup{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
return exo.BooleanAsyncRequest(req, async)
|
||||||
|
}
|
42
vendor/github.com/exoscale/egoscale/affinitygroup.go
generated
vendored
42
vendor/github.com/exoscale/egoscale/affinitygroup.go
generated
vendored
|
@ -1,42 +0,0 @@
|
||||||
package egoscale
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/url"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (exo *Client) CreateAffinityGroup(name string) (string, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("name", name)
|
|
||||||
params.Set("type", "host anti-affinity")
|
|
||||||
|
|
||||||
resp, err := exo.Request("createAffinityGroup", params)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r CreateAffinityGroupResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.JobId, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) DeleteAffinityGroup(name string) (string, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("name", name)
|
|
||||||
|
|
||||||
resp, err := exo.Request("deleteAffinityGroup", params)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r DeleteAffinityGroupResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.JobId, nil
|
|
||||||
|
|
||||||
}
|
|
52
vendor/github.com/exoscale/egoscale/apis.go
generated
vendored
Normal file
52
vendor/github.com/exoscale/egoscale/apis.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// API represents an API service
|
||||||
|
type API struct {
|
||||||
|
Description string `json:"description"`
|
||||||
|
IsAsync bool `json:"isasync"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Related string `json:"related"` // comma separated
|
||||||
|
Since string `json:"since"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Params []APIParam `json:"params"`
|
||||||
|
Response []APIResponse `json:"responses"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIParam represents an API parameter field
|
||||||
|
type APIParam struct {
|
||||||
|
Description string `json:"description"`
|
||||||
|
Length int64 `json:"length"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Related string `json:"related"` // comma separated
|
||||||
|
Since string `json:"since"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIResponse represents an API response field
|
||||||
|
type APIResponse struct {
|
||||||
|
Description string `json:"description"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Response []APIResponse `json:"response"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAPIs represents a query to list the api
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listApis.html
|
||||||
|
type ListAPIs struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListAPIs) name() string {
|
||||||
|
return "listApis"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListAPIs) response() interface{} {
|
||||||
|
return new(ListAPIsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAPIsResponse represents a list of API
|
||||||
|
type ListAPIsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
API []API `json:"api"`
|
||||||
|
}
|
36
vendor/github.com/exoscale/egoscale/async.go
generated
vendored
36
vendor/github.com/exoscale/egoscale/async.go
generated
vendored
|
@ -1,36 +0,0 @@
|
||||||
package egoscale
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/url"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (exo *Client) PollAsyncJob(jobid string) (*QueryAsyncJobResultResponse, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
|
|
||||||
params.Set("jobid", jobid)
|
|
||||||
|
|
||||||
resp, err := exo.Request("queryAsyncJobResult", params)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r QueryAsyncJobResultResponse
|
|
||||||
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) AsyncToVirtualMachine(resp QueryAsyncJobResultResponse) (*DeployVirtualMachineResponse, error) {
|
|
||||||
var r DeployVirtualMachineWrappedResponse
|
|
||||||
|
|
||||||
if err := json.Unmarshal(resp.Jobresult, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r.Wrapped, nil
|
|
||||||
}
|
|
66
vendor/github.com/exoscale/egoscale/async_jobs.go
generated
vendored
Normal file
66
vendor/github.com/exoscale/egoscale/async_jobs.go
generated
vendored
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AsyncJobResult represents an asynchronous job result
|
||||||
|
type AsyncJobResult struct {
|
||||||
|
AccountID string `json:"accountid"`
|
||||||
|
Cmd string `json:"cmd"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
JobInstanceID string `json:"jobinstanceid"`
|
||||||
|
JobInstanceType string `json:"jobinstancetype"`
|
||||||
|
JobProcStatus int `json:"jobprocstatus"`
|
||||||
|
JobResult *json.RawMessage `json:"jobresult"`
|
||||||
|
JobResultCode int `json:"jobresultcode"`
|
||||||
|
JobResultType string `json:"jobresulttype"`
|
||||||
|
JobStatus JobStatusType `json:"jobstatus"`
|
||||||
|
UserID string `json:"userid"`
|
||||||
|
JobID string `json:"jobid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryAsyncJobResult represents a query to fetch the status of async job
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/queryAsyncJobResult.html
|
||||||
|
type QueryAsyncJobResult struct {
|
||||||
|
JobID string `json:"jobid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*QueryAsyncJobResult) name() string {
|
||||||
|
return "queryAsyncJobResult"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*QueryAsyncJobResult) response() interface{} {
|
||||||
|
return new(QueryAsyncJobResultResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryAsyncJobResultResponse represents the current status of an asynchronous job
|
||||||
|
type QueryAsyncJobResultResponse AsyncJobResult
|
||||||
|
|
||||||
|
// ListAsyncJobs list the asynchronous jobs
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listAsyncJobs.html
|
||||||
|
type ListAsyncJobs struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
StartDate string `json:"startdate,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListAsyncJobs) name() string {
|
||||||
|
return "listAsyncJobs"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListAsyncJobs) response() interface{} {
|
||||||
|
return new(ListAsyncJobsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAsyncJobsResponse represents a list of job results
|
||||||
|
type ListAsyncJobsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
AsyncJobs []AsyncJobResult `json:"asyncjobs"`
|
||||||
|
}
|
241
vendor/github.com/exoscale/egoscale/dns.go
generated
vendored
241
vendor/github.com/exoscale/egoscale/dns.go
generated
vendored
|
@ -2,59 +2,118 @@ package egoscale
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DNSDomain represents a domain
|
||||||
|
type DNSDomain struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
AccountID int64 `json:"account_id,omitempty"`
|
||||||
|
UserID int64 `json:"user_id,omitempty"`
|
||||||
|
RegistrantID int64 `json:"registrant_id,omitempty"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
UnicodeName string `json:"unicode_name"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
State string `json:"state"`
|
||||||
|
Language string `json:"language,omitempty"`
|
||||||
|
Lockable bool `json:"lockable"`
|
||||||
|
AutoRenew bool `json:"auto_renew"`
|
||||||
|
WhoisProtected bool `json:"whois_protected"`
|
||||||
|
RecordCount int64 `json:"record_count"`
|
||||||
|
ServiceCount int64 `json:"service_count"`
|
||||||
|
ExpiresOn string `json:"expires_on,omitempty"`
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
UpdatedAt string `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSDomainResponse represents a domain creation response
|
||||||
|
type DNSDomainResponse struct {
|
||||||
|
Domain *DNSDomain `json:"domain"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSRecord represents a DNS record
|
||||||
|
type DNSRecord struct {
|
||||||
|
ID int64 `json:"id,omitempty"`
|
||||||
|
DomainID int64 `json:"domain_id,omitempty"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
TTL int `json:"ttl,omitempty"`
|
||||||
|
CreatedAt string `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt string `json:"updated_at,omitempty"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
RecordType string `json:"record_type"`
|
||||||
|
Prio int `json:"prio,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSRecordResponse represents the creation of a DNS record
|
||||||
|
type DNSRecordResponse struct {
|
||||||
|
Record DNSRecord `json:"record"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSErrorResponse represents an error in the API
|
||||||
|
type DNSErrorResponse struct {
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
Errors *DNSError `json:"errors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSError represents an error
|
||||||
|
type DNSError struct {
|
||||||
|
Name []string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error formats the DNSerror into a string
|
||||||
|
func (req *DNSErrorResponse) Error() error {
|
||||||
|
if req.Errors != nil {
|
||||||
|
return fmt.Errorf("DNS error: %s", strings.Join(req.Errors.Name, ", "))
|
||||||
|
}
|
||||||
|
return fmt.Errorf("DNS error: %s", req.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateDomain creates a DNS domain
|
||||||
func (exo *Client) CreateDomain(name string) (*DNSDomain, error) {
|
func (exo *Client) CreateDomain(name string) (*DNSDomain, error) {
|
||||||
var hdr = make(http.Header)
|
m, err := json.Marshal(DNSDomainResponse{
|
||||||
var domain DNSDomainCreateRequest
|
Domain: &DNSDomain{
|
||||||
|
Name: name,
|
||||||
hdr.Add("X-DNS-TOKEN", exo.apiKey+":"+exo.apiSecret)
|
},
|
||||||
domain.Domain.Name = name
|
})
|
||||||
m, err := json.Marshal(domain)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := exo.DetailedRequest("/v1/domains", string(m), "POST", hdr)
|
resp, err := exo.dnsRequest("/v1/domains", string(m), "POST")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var d *DNSDomain
|
var d *DNSDomainResponse
|
||||||
if err := json.Unmarshal(resp, &d); err != nil {
|
if err := json.Unmarshal(resp, &d); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return d, nil
|
return d.Domain, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDomain gets a DNS domain
|
||||||
func (exo *Client) GetDomain(name string) (*DNSDomain, error) {
|
func (exo *Client) GetDomain(name string) (*DNSDomain, error) {
|
||||||
var hdr = make(http.Header)
|
resp, err := exo.dnsRequest("/v1/domains/"+name, "", "GET")
|
||||||
|
|
||||||
hdr.Add("X-DNS-TOKEN", exo.apiKey+":"+exo.apiSecret)
|
|
||||||
hdr.Add("Accept", "application/json")
|
|
||||||
|
|
||||||
resp, err := exo.DetailedRequest("/v1/domains/"+name, "", "GET", hdr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var d *DNSDomain
|
var d *DNSDomainResponse
|
||||||
if err := json.Unmarshal(resp, &d); err != nil {
|
if err := json.Unmarshal(resp, &d); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return d, nil
|
return d.Domain, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteDomain delets a DNS domain
|
||||||
func (exo *Client) DeleteDomain(name string) error {
|
func (exo *Client) DeleteDomain(name string) error {
|
||||||
var hdr = make(http.Header)
|
_, err := exo.dnsRequest("/v1/domains/"+name, "", "DELETE")
|
||||||
hdr.Add("X-DNS-TOKEN", exo.apiKey+":"+exo.apiSecret)
|
|
||||||
hdr.Add("Accept", "application/json")
|
|
||||||
|
|
||||||
_, err := exo.DetailedRequest("/v1/domains/"+name, "", "DELETE", hdr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -62,92 +121,128 @@ func (exo *Client) DeleteDomain(name string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (exo *Client) GetRecords(name string) ([]*DNSRecordResponse, error) {
|
// GetRecord returns a DNS record
|
||||||
var hdr = make(http.Header)
|
func (exo *Client) GetRecord(domain string, recordID int64) (*DNSRecord, error) {
|
||||||
hdr.Add("X-DNS-TOKEN", exo.apiKey+":"+exo.apiSecret)
|
id := strconv.FormatInt(recordID, 10)
|
||||||
hdr.Add("Accept", "application/json")
|
resp, err := exo.dnsRequest("/v1/domains/"+domain+"/records/"+id, "", "GET")
|
||||||
|
|
||||||
resp, err := exo.DetailedRequest("/v1/domains/"+name+"/records", "", "GET", hdr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var r []*DNSRecordResponse
|
var r DNSRecordResponse
|
||||||
if err = json.Unmarshal(resp, &r); err != nil {
|
if err = json.Unmarshal(resp, &r); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return r, nil
|
return &(r.Record), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (exo *Client) CreateRecord(name string, rec DNSRecord) (*DNSRecordResponse, error) {
|
// GetRecords returns the DNS records
|
||||||
var hdr = make(http.Header)
|
func (exo *Client) GetRecords(name string) ([]DNSRecord, error) {
|
||||||
hdr.Add("X-DNS-TOKEN", exo.apiKey+":"+exo.apiSecret)
|
resp, err := exo.dnsRequest("/v1/domains/"+name+"/records", "", "GET")
|
||||||
hdr.Add("Accept", "application/json")
|
|
||||||
hdr.Add("Content-Type", "application/json")
|
|
||||||
|
|
||||||
var rr DNSRecordResponse
|
|
||||||
rr.Record = rec
|
|
||||||
|
|
||||||
body, err := json.Marshal(rr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := exo.DetailedRequest("/v1/domains/"+name+"/records", string(body), "POST", hdr)
|
var r []DNSRecordResponse
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r *DNSRecordResponse
|
|
||||||
if err = json.Unmarshal(resp, &r); err != nil {
|
if err = json.Unmarshal(resp, &r); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return r, nil
|
records := make([]DNSRecord, 0, len(r))
|
||||||
|
for _, rec := range r {
|
||||||
|
records = append(records, rec.Record)
|
||||||
|
}
|
||||||
|
|
||||||
|
return records, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (exo *Client) UpdateRecord(name string, rec DNSRecord) (*DNSRecordResponse, error) {
|
// CreateRecord creates a DNS record
|
||||||
var hdr = make(http.Header)
|
func (exo *Client) CreateRecord(name string, rec DNSRecord) (*DNSRecord, error) {
|
||||||
id := strconv.FormatInt(rec.Id, 10)
|
body, err := json.Marshal(DNSRecordResponse{
|
||||||
hdr.Add("X-DNS-TOKEN", exo.apiKey+":"+exo.apiSecret)
|
Record: rec,
|
||||||
hdr.Add("Accept", "application/json")
|
})
|
||||||
hdr.Add("Content-Type", "application/json")
|
|
||||||
|
|
||||||
var rr DNSRecordResponse
|
|
||||||
rr.Record = rec
|
|
||||||
|
|
||||||
body, err := json.Marshal(rr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := exo.DetailedRequest("/v1/domains/"+name+"/records/"+id,
|
resp, err := exo.dnsRequest("/v1/domains/"+name+"/records", string(body), "POST")
|
||||||
string(body), "PUT", hdr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var r *DNSRecordResponse
|
var r DNSRecordResponse
|
||||||
if err = json.Unmarshal(resp, &r); err != nil {
|
if err = json.Unmarshal(resp, &r); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return r, nil
|
return &(r.Record), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (exo *Client) DeleteRecord(name string, rec DNSRecord) error {
|
// UpdateRecord updates a DNS record
|
||||||
var hdr = make(http.Header)
|
func (exo *Client) UpdateRecord(name string, rec DNSRecord) (*DNSRecord, error) {
|
||||||
id := strconv.FormatInt(rec.Id, 10)
|
body, err := json.Marshal(DNSRecordResponse{
|
||||||
hdr.Add("X-DNS-TOKEN", exo.apiKey+":"+exo.apiSecret)
|
Record: rec,
|
||||||
hdr.Add("Accept", "application/json")
|
})
|
||||||
hdr.Add("Content-Type", "application/json")
|
|
||||||
|
|
||||||
_, err := exo.DetailedRequest("/v1/domains/"+name+"/records/"+id,
|
|
||||||
"", "DELETE", hdr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
id := strconv.FormatInt(rec.ID, 10)
|
||||||
|
resp, err := exo.dnsRequest("/v1/domains/"+name+"/records/"+id, string(body), "PUT")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var r DNSRecordResponse
|
||||||
|
if err = json.Unmarshal(resp, &r); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &(r.Record), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRecord deletes a record
|
||||||
|
func (exo *Client) DeleteRecord(name string, recordID int64) error {
|
||||||
|
id := strconv.FormatInt(recordID, 10)
|
||||||
|
_, err := exo.dnsRequest("/v1/domains/"+name+"/records/"+id, "", "DELETE")
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (exo *Client) dnsRequest(uri string, params string, method string) (json.RawMessage, error) {
|
||||||
|
url := exo.endpoint + uri
|
||||||
|
req, err := http.NewRequest(method, url, strings.NewReader(params))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var hdr = make(http.Header)
|
||||||
|
hdr.Add("X-DNS-TOKEN", exo.apiKey+":"+exo.apiSecret)
|
||||||
|
hdr.Add("Accept", "application/json")
|
||||||
|
if params != "" {
|
||||||
|
hdr.Add("Content-Type", "application/json")
|
||||||
|
}
|
||||||
|
req.Header = hdr
|
||||||
|
|
||||||
|
response, err := exo.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer response.Body.Close()
|
||||||
|
b, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.StatusCode >= 400 {
|
||||||
|
var e DNSErrorResponse
|
||||||
|
if err := json.Unmarshal(b, &e); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nil, e.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
93
vendor/github.com/exoscale/egoscale/doc.go
generated
vendored
Normal file
93
vendor/github.com/exoscale/egoscale/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Package egoscale is a mapping for with the CloudStack API (http://cloudstack.apache.org/api.html) from Go. It has been designed against the Exoscale (https://www.exoscale.ch/) infrastructure but should fit other CloudStack services.
|
||||||
|
|
||||||
|
Requests and Responses
|
||||||
|
|
||||||
|
The paradigm used in this library is that CloudStack defines two types of requests synchronous (client.Request) and asynchronous (client.AsyncRequest). And when the expected responses is a success message, you may use the boolean requests variants (client.BooleanRequest, client.BooleanAsyncRequest). To build a request, construct the adequate struct. This library expects a pointer for efficiency reasons only. The response is a struct corresponding to the request itself. E.g. DeployVirtualMachine gives DeployVirtualMachineResponse, as a pointer as well to avoid big copies.
|
||||||
|
|
||||||
|
Then everything within the struct is not a pointer.
|
||||||
|
|
||||||
|
Affinity and Anti-Affinity groups
|
||||||
|
|
||||||
|
Affinity and Anti-Affinity groups provide a way to influence where VMs should run. See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/virtual_machines.html#affinity-groups
|
||||||
|
|
||||||
|
APIs
|
||||||
|
|
||||||
|
All the available APIs on the server and provided by the API Discovery plugin
|
||||||
|
|
||||||
|
cs := egoscale.NewClient("https://api.exoscale.ch/compute", "EXO...", "...")
|
||||||
|
|
||||||
|
resp, err := cs.Request(&egoscale.ListAPIs{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, api := range resp.(*egoscale.ListAPIsResponse).API {
|
||||||
|
fmt.Println("%s %s", api.Name, api.Description)
|
||||||
|
}
|
||||||
|
// Output:
|
||||||
|
// listNetworks Lists all available networks
|
||||||
|
// ...
|
||||||
|
|
||||||
|
|
||||||
|
Elastic IPs
|
||||||
|
|
||||||
|
See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/networking_and_traffic.html#about-elastic-ips
|
||||||
|
|
||||||
|
Networks
|
||||||
|
|
||||||
|
See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/4.8/networking_and_traffic.html
|
||||||
|
|
||||||
|
NICs
|
||||||
|
|
||||||
|
See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/networking_and_traffic.html#configuring-multiple-ip-addresses-on-a-single-nic
|
||||||
|
|
||||||
|
|
||||||
|
Security Groups
|
||||||
|
|
||||||
|
Security Groups provide a way to isolate traffic to VMs.
|
||||||
|
|
||||||
|
resp, err := cs.Request(&egoscale.CreateSecurityGroup{
|
||||||
|
Name: "Load balancer",
|
||||||
|
Description: "Opens HTTP/HTTPS ports from the outside world",
|
||||||
|
})
|
||||||
|
securityGroup := resp.(*egoscale.CreateSecurityGroupResponse).SecurityGroup
|
||||||
|
// ...
|
||||||
|
err = client.BooleanRequest(&egoscale.DeleteSecurityGroup{
|
||||||
|
ID: securityGroup.ID,
|
||||||
|
})
|
||||||
|
// ...
|
||||||
|
|
||||||
|
See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/networking_and_traffic.html#security-groups
|
||||||
|
|
||||||
|
Service Offerings
|
||||||
|
|
||||||
|
A service offering correspond to some hardware features (CPU, RAM).
|
||||||
|
|
||||||
|
See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/service_offerings.html
|
||||||
|
|
||||||
|
SSH Key Pairs
|
||||||
|
|
||||||
|
In addition to username and password (disabled on Exoscale), SSH keys are used to log into the infrastructure.
|
||||||
|
|
||||||
|
See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/virtual_machines.html#creating-the-ssh-keypair
|
||||||
|
|
||||||
|
Virtual Machines
|
||||||
|
|
||||||
|
... todo ...
|
||||||
|
|
||||||
|
See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/virtual_machines.html
|
||||||
|
|
||||||
|
Templates
|
||||||
|
|
||||||
|
... todo ...
|
||||||
|
|
||||||
|
See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/templates.html
|
||||||
|
|
||||||
|
Zones
|
||||||
|
|
||||||
|
A Zone corresponds to a Data Center.
|
||||||
|
|
||||||
|
*/
|
||||||
|
package egoscale
|
9
vendor/github.com/exoscale/egoscale/error.go
generated
vendored
9
vendor/github.com/exoscale/egoscale/error.go
generated
vendored
|
@ -1,9 +0,0 @@
|
||||||
package egoscale
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (e *Error) Error() error {
|
|
||||||
return fmt.Errorf("exoscale API error %d (internal code: %d): %s", e.ErrorCode, e.CSErrorCode, e.ErrorText)
|
|
||||||
}
|
|
77
vendor/github.com/exoscale/egoscale/events.go
generated
vendored
Normal file
77
vendor/github.com/exoscale/egoscale/events.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// Event represents an event in the system
|
||||||
|
type Event struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Account string `json:"account"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Level string `json:"level"` // INFO, WARN, ERROR
|
||||||
|
ParentID string `json:"parentid,omitempty"`
|
||||||
|
Project string `json:"project,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
UserName string `json:"username,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EventType represent a type of event
|
||||||
|
type EventType struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEvents list the events
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listEvents.html
|
||||||
|
type ListEvents struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Duration int `json:"duration,omitempty"`
|
||||||
|
EndDate string `json:"enddate,omitempty"`
|
||||||
|
EntryTime int `json:"entrytime,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
Level string `json:"level,omitempty"` // INFO, WARN, ERROR
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
StartDate string `json:"startdate,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListEvents) name() string {
|
||||||
|
return "listEvents"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListEvents) response() interface{} {
|
||||||
|
return new(ListEventsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEventsResponse represents a response of a list query
|
||||||
|
type ListEventsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
Event []Event `json:"event"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEventTypes list the event types
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listEventTypes.html
|
||||||
|
type ListEventTypes struct{}
|
||||||
|
|
||||||
|
func (*ListEventTypes) name() string {
|
||||||
|
return "listEventTypes"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListEventTypes) response() interface{} {
|
||||||
|
return new(ListEventTypesResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListEventTypesResponse represents a response of a list query
|
||||||
|
type ListEventTypesResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
EventType []EventType `json:"eventtype"`
|
||||||
|
}
|
144
vendor/github.com/exoscale/egoscale/groups.go
generated
vendored
144
vendor/github.com/exoscale/egoscale/groups.go
generated
vendored
|
@ -1,144 +0,0 @@
|
||||||
package egoscale
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (exo *Client) CreateEgressRule(rule SecurityGroupRule) (*AuthorizeSecurityGroupEgressResponse, error) {
|
|
||||||
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("securitygroupid", rule.SecurityGroupId)
|
|
||||||
|
|
||||||
if rule.Cidr != "" {
|
|
||||||
params.Set("cidrlist", rule.Cidr)
|
|
||||||
} else if len(rule.UserSecurityGroupList) > 0 {
|
|
||||||
usg, err := json.Marshal(rule.UserSecurityGroupList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
params.Set("usersecuritygrouplist", string(usg))
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("No Egress rule CIDR or Security Group List provided")
|
|
||||||
}
|
|
||||||
|
|
||||||
params.Set("protocol", rule.Protocol)
|
|
||||||
|
|
||||||
if rule.Protocol == "ICMP" {
|
|
||||||
params.Set("icmpcode", fmt.Sprintf("%d", rule.IcmpCode))
|
|
||||||
params.Set("icmptype", fmt.Sprintf("%d", rule.IcmpType))
|
|
||||||
} else if rule.Protocol == "TCP" || rule.Protocol == "UDP" {
|
|
||||||
params.Set("startport", fmt.Sprintf("%d", rule.Port))
|
|
||||||
params.Set("endport", fmt.Sprintf("%d", rule.Port))
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("Invalid Egress rule Protocol: %s", rule.Protocol)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := exo.Request("authorizeSecurityGroupEgress", params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r AuthorizeSecurityGroupEgressResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) CreateIngressRule(rule SecurityGroupRule) (*AuthorizeSecurityGroupIngressResponse, error) {
|
|
||||||
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("securitygroupid", rule.SecurityGroupId)
|
|
||||||
|
|
||||||
if rule.Cidr != "" {
|
|
||||||
params.Set("cidrlist", rule.Cidr)
|
|
||||||
} else if len(rule.UserSecurityGroupList) > 0 {
|
|
||||||
for i := 0; i < len(rule.UserSecurityGroupList); i++ {
|
|
||||||
params.Set(fmt.Sprintf("usersecuritygrouplist[%d].account", i), rule.UserSecurityGroupList[i].Account)
|
|
||||||
params.Set(fmt.Sprintf("usersecuritygrouplist[%d].group", i), rule.UserSecurityGroupList[i].Group)
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("No Ingress rule CIDR or Security Group List provided")
|
|
||||||
}
|
|
||||||
|
|
||||||
params.Set("protocol", rule.Protocol)
|
|
||||||
|
|
||||||
if rule.Protocol == "ICMP" {
|
|
||||||
params.Set("icmpcode", fmt.Sprintf("%d", rule.IcmpCode))
|
|
||||||
params.Set("icmptype", fmt.Sprintf("%d", rule.IcmpType))
|
|
||||||
} else if rule.Protocol == "TCP" || rule.Protocol == "UDP" {
|
|
||||||
params.Set("startport", fmt.Sprintf("%d", rule.Port))
|
|
||||||
params.Set("endport", fmt.Sprintf("%d", rule.Port))
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("Invalid Egress rule Protocol: %s", rule.Protocol)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("## params: %+v\n", params)
|
|
||||||
|
|
||||||
resp, err := exo.Request("authorizeSecurityGroupIngress", params)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r AuthorizeSecurityGroupIngressResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) CreateSecurityGroupWithRules(name string, ingress []SecurityGroupRule, egress []SecurityGroupRule) (*CreateSecurityGroupResponse, error) {
|
|
||||||
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("name", name)
|
|
||||||
|
|
||||||
resp, err := exo.Request("createSecurityGroup", params)
|
|
||||||
|
|
||||||
var r CreateSecurityGroupResponseWrapper
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sgid := r.Wrapped.Id
|
|
||||||
|
|
||||||
for _, erule := range egress {
|
|
||||||
erule.SecurityGroupId = sgid
|
|
||||||
_, err = exo.CreateEgressRule(erule)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, inrule := range ingress {
|
|
||||||
inrule.SecurityGroupId = sgid
|
|
||||||
_, err = exo.CreateIngressRule(inrule)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r.Wrapped, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) DeleteSecurityGroup(name string) error {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("name", name)
|
|
||||||
|
|
||||||
resp, err := exo.Request("deleteSecurityGroup", params)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("## response: %+v\n", resp)
|
|
||||||
return nil
|
|
||||||
}
|
|
1
vendor/github.com/exoscale/egoscale/init.go
generated
vendored
1
vendor/github.com/exoscale/egoscale/init.go
generated
vendored
|
@ -5,6 +5,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewClient creates a CloudStack API client
|
||||||
func NewClient(endpoint string, apiKey string, apiSecret string) *Client {
|
func NewClient(endpoint string, apiKey string, apiSecret string) *Client {
|
||||||
cs := &Client{
|
cs := &Client{
|
||||||
client: &http.Client{
|
client: &http.Client{
|
||||||
|
|
40
vendor/github.com/exoscale/egoscale/ip.go
generated
vendored
40
vendor/github.com/exoscale/egoscale/ip.go
generated
vendored
|
@ -1,40 +0,0 @@
|
||||||
package egoscale
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/url"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (exo *Client) AddIpToNic(nic_id string, ip_address string) (string, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("nicid", nic_id)
|
|
||||||
params.Set("ipaddress", ip_address)
|
|
||||||
|
|
||||||
resp, err := exo.Request("addIpToNic", params)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r AddIpToNicResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.Id, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) RemoveIpFromNic(nic_id string) (string, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("id", nic_id)
|
|
||||||
|
|
||||||
resp, err := exo.Request("removeIpFromNic", params)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r RemoveIpFromNicResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return r.JobID, nil
|
|
||||||
}
|
|
59
vendor/github.com/exoscale/egoscale/keypair.go
generated
vendored
59
vendor/github.com/exoscale/egoscale/keypair.go
generated
vendored
|
@ -1,59 +0,0 @@
|
||||||
package egoscale
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/url"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (exo *Client) CreateKeypair(name string) (*CreateSSHKeyPairResponse, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("name", name)
|
|
||||||
|
|
||||||
resp, err := exo.Request("createSSHKeyPair", params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r CreateSSHKeyPairWrappedResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r.Wrapped, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) DeleteKeypair(name string) (*StandardResponse, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("name", name)
|
|
||||||
|
|
||||||
resp, err := exo.Request("deleteSSHKeyPair", params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r StandardResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) RegisterKeypair(name string, key string) (*CreateSSHKeyPairResponse, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("name", name)
|
|
||||||
params.Set("publicKey", key)
|
|
||||||
|
|
||||||
resp, err := exo.Request("registerSSHKeyPair", params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r CreateSSHKeyPairWrappedResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r.Wrapped, nil
|
|
||||||
}
|
|
171
vendor/github.com/exoscale/egoscale/keypairs.go
generated
vendored
Normal file
171
vendor/github.com/exoscale/egoscale/keypairs.go
generated
vendored
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// SSHKeyPair represents an SSH key pair
|
||||||
|
type SSHKeyPair struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
Fingerprint string `json:"fingerprint,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
PrivateKey string `json:"privatekey,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSSHKeyPair represents a new keypair to be created
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createSSHKeyPair.html
|
||||||
|
type CreateSSHKeyPair struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateSSHKeyPair) name() string {
|
||||||
|
return "createSSHKeyPair"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateSSHKeyPair) response() interface{} {
|
||||||
|
return new(CreateSSHKeyPairResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSSHKeyPairResponse represents the creation of an SSH Key Pair
|
||||||
|
type CreateSSHKeyPairResponse struct {
|
||||||
|
KeyPair SSHKeyPair `json:"keypair"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSSHKeyPair represents a new keypair to be created
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteSSHKeyPair.html
|
||||||
|
type DeleteSSHKeyPair struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteSSHKeyPair) name() string {
|
||||||
|
return "deleteSSHKeyPair"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteSSHKeyPair) response() interface{} {
|
||||||
|
return new(booleanSyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterSSHKeyPair represents a new registration of a public key in a keypair
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/registerSSHKeyPair.html
|
||||||
|
type RegisterSSHKeyPair struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
PublicKey string `json:"publickey"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RegisterSSHKeyPair) name() string {
|
||||||
|
return "registerSSHKeyPair"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RegisterSSHKeyPair) response() interface{} {
|
||||||
|
return new(RegisterSSHKeyPairResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterSSHKeyPairResponse represents the creation of an SSH Key Pair
|
||||||
|
type RegisterSSHKeyPairResponse struct {
|
||||||
|
KeyPair SSHKeyPair `json:"keypair"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListSSHKeyPairs represents a query for a list of SSH KeyPairs
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listSSHKeyPairs.html
|
||||||
|
type ListSSHKeyPairs struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Fingerprint string `json:"fingerprint,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListSSHKeyPairs) name() string {
|
||||||
|
return "listSSHKeyPairs"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListSSHKeyPairs) response() interface{} {
|
||||||
|
return new(ListSSHKeyPairsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListSSHKeyPairsResponse represents a list of SSH key pairs
|
||||||
|
type ListSSHKeyPairsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
SSHKeyPair []SSHKeyPair `json:"sshkeypair"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetSSHKeyForVirtualMachine (Async) represents a change for the key pairs
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/resetSSHKeyForVirtualMachine.html
|
||||||
|
type ResetSSHKeyForVirtualMachine struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
KeyPair string `json:"keypair"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ResetSSHKeyForVirtualMachine) name() string {
|
||||||
|
return "resetSSHKeyForVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ResetSSHKeyForVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(ResetSSHKeyForVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetSSHKeyForVirtualMachineResponse represents the modified VirtualMachine
|
||||||
|
type ResetSSHKeyForVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// CreateKeypair create a new SSH Key Pair
|
||||||
|
//
|
||||||
|
// Deprecated: will go away, use the API directly
|
||||||
|
func (exo *Client) CreateKeypair(name string) (*SSHKeyPair, error) {
|
||||||
|
req := &CreateSSHKeyPair{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
resp, err := exo.Request(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
keypair := resp.(*CreateSSHKeyPairResponse).KeyPair
|
||||||
|
return &keypair, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteKeypair deletes an SSH key pair
|
||||||
|
//
|
||||||
|
// Deprecated: will go away, use the API directly
|
||||||
|
func (exo *Client) DeleteKeypair(name string) error {
|
||||||
|
req := &DeleteSSHKeyPair{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
return exo.BooleanRequest(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterKeypair registers a public key in a keypair
|
||||||
|
//
|
||||||
|
// Deprecated: will go away, use the API directly
|
||||||
|
func (exo *Client) RegisterKeypair(name string, publicKey string) (*SSHKeyPair, error) {
|
||||||
|
req := &RegisterSSHKeyPair{
|
||||||
|
Name: name,
|
||||||
|
PublicKey: publicKey,
|
||||||
|
}
|
||||||
|
resp, err := exo.Request(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
keypair := resp.(*RegisterSSHKeyPairResponse).KeyPair
|
||||||
|
return &keypair, nil
|
||||||
|
}
|
106
vendor/github.com/exoscale/egoscale/limits.go
generated
vendored
Normal file
106
vendor/github.com/exoscale/egoscale/limits.go
generated
vendored
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// https://github.com/apache/cloudstack/blob/master/api/src/main/java/com/cloud/configuration/Resource.java
|
||||||
|
|
||||||
|
// ResourceTypeName represents the name of a resource type (for limits)
|
||||||
|
type ResourceTypeName string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// VirtualMachineTypeName is the resource type name of a VM
|
||||||
|
VirtualMachineTypeName ResourceTypeName = "user_vm"
|
||||||
|
// IPAddressTypeName is the resource type name of an IP address
|
||||||
|
IPAddressTypeName = "public_ip"
|
||||||
|
// VolumeTypeName is the resource type name of a volume
|
||||||
|
VolumeTypeName = "volume"
|
||||||
|
// SnapshotTypeName is the resource type name of a snapshot
|
||||||
|
SnapshotTypeName = "snapshot"
|
||||||
|
// TemplateTypeName is the resource type name of a template
|
||||||
|
TemplateTypeName = "template"
|
||||||
|
// ProjectTypeName is the resource type name of a project
|
||||||
|
ProjectTypeName = "project"
|
||||||
|
// NetworkTypeName is the resource type name of a network
|
||||||
|
NetworkTypeName = "network"
|
||||||
|
// VPCTypeName is the resource type name of a VPC
|
||||||
|
VPCTypeName = "vpc"
|
||||||
|
// CPUTypeName is the resource type name of a CPU
|
||||||
|
CPUTypeName = "cpu"
|
||||||
|
// MemoryTypeName is the resource type name of Memory
|
||||||
|
MemoryTypeName = "memory"
|
||||||
|
// PrimaryStorageTypeName is the resource type name of primary storage
|
||||||
|
PrimaryStorageTypeName = "primary_storage"
|
||||||
|
// SecondaryStorageTypeName is the resource type name of secondary storage
|
||||||
|
SecondaryStorageTypeName = "secondary_storage"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ResourceType represents the ID of a resource type (for limits)
|
||||||
|
type ResourceType int64
|
||||||
|
|
||||||
|
const (
|
||||||
|
// VirtualMachineType is the resource type ID of a VM
|
||||||
|
VirtualMachineType ResourceType = iota
|
||||||
|
// IPAddressType is the resource type ID of an IP address
|
||||||
|
IPAddressType
|
||||||
|
// VolumeType is the resource type ID of a volume
|
||||||
|
VolumeType
|
||||||
|
// SnapshotType is the resource type ID of a snapshot
|
||||||
|
SnapshotType
|
||||||
|
// TemplateType is the resource type ID of a template
|
||||||
|
TemplateType
|
||||||
|
// ProjectType is the resource type ID of a project
|
||||||
|
ProjectType
|
||||||
|
// NetworkType is the resource type ID of a network
|
||||||
|
NetworkType
|
||||||
|
// VPCType is the resource type ID of a VPC
|
||||||
|
VPCType
|
||||||
|
// CPUType is the resource type ID of a CPU
|
||||||
|
CPUType
|
||||||
|
// MemoryType is the resource type ID of Memory
|
||||||
|
MemoryType
|
||||||
|
// PrimaryStorageType is the resource type ID of primary storage
|
||||||
|
PrimaryStorageType
|
||||||
|
// SecondaryStorageType is the resource type ID of secondary storage
|
||||||
|
SecondaryStorageType
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListResourceLimits lists the resource limits
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listResourceLimits.html
|
||||||
|
type ListResourceLimits struct {
|
||||||
|
Account string `json:"account,omittempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
ResourceType ResourceType `json:"resourcetype,omitempty"`
|
||||||
|
ResourceTypeName ResourceTypeName `json:"resourcetypename,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListResourceLimits) name() string {
|
||||||
|
return "listResourceLimits"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListResourceLimits) response() interface{} {
|
||||||
|
return new(ListResourceLimitsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListResourceLimitsResponse represents a list of resource limits
|
||||||
|
type ListResourceLimitsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
ResourceLimit []ResourceLimit `json:"resourcelimit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceLimit represents the limit on a particular resource
|
||||||
|
type ResourceLimit struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Max int64 `json:"max,omitempty"` // -1 means the sky is the limit
|
||||||
|
Project string `json:"project,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
ResourceType ResourceType `json:"resourcetype,omitempty"`
|
||||||
|
ResourceTypeName ResourceTypeName `json:"resourcetypename,omitempty"`
|
||||||
|
}
|
68
vendor/github.com/exoscale/egoscale/network_offerings.go
generated
vendored
Normal file
68
vendor/github.com/exoscale/egoscale/network_offerings.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// NetworkOffering corresponds to the Compute Offerings
|
||||||
|
type NetworkOffering struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Availability string `json:"availability,omitempty"`
|
||||||
|
ConserveMode bool `json:"conservemode,omitempty"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
Details map[string]string `json:"details,omitempty"`
|
||||||
|
DisplayText string `json:"displaytext,omitempty"`
|
||||||
|
EgressDefaultPolicy bool `json:"egressdefaultpolicy,omitempty"`
|
||||||
|
ForVPC bool `json:"forvpc,omitempty"`
|
||||||
|
GuestIPType string `json:"guestiptype,omitempty"`
|
||||||
|
IsDefault bool `json:"isdefault,omitempty"`
|
||||||
|
IsPersistent bool `json:"ispersistent,omitempty"`
|
||||||
|
MaxConnections int `json:"maxconnections,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkRate int `json:"networkrate,omitempty"`
|
||||||
|
ServiceOfferingID string `json:"serviceofferingid,omitempty"`
|
||||||
|
SpecifyIPRanges bool `json:"specifyipranges,omitempty"`
|
||||||
|
SpecifyVlan bool `json:"specifyvlan,omitempty"`
|
||||||
|
State string `json:"state"` // Disabled/Enabled/Inactive
|
||||||
|
SupportsPublicAccess bool `json:"supportspublicaccess,omitempty"`
|
||||||
|
SupportsStrechedL2Subnet bool `json:"supportsstrechedl2subnet,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
TrafficType string `json:"traffictype,omitempty"` // Public, Management, Control, ...
|
||||||
|
Service []Service `json:"service,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListNetworkOfferings represents a query for network offerings
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listNetworkOfferings.html
|
||||||
|
type ListNetworkOfferings struct {
|
||||||
|
Availability string `json:"availability,omitempty"`
|
||||||
|
DisplayText string `json:"displaytext,omitempty"`
|
||||||
|
ForVPC bool `json:"forvpc,omitempty"`
|
||||||
|
GuestIPType string `json:"guestiptype,omitempty"` // shared of isolated
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsDefault bool `json:"isdefault,omitempty"`
|
||||||
|
IsTagged bool `json:"istagged,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkID string `json:"networkid,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
SourceNATSupported bool `json:"sourcenatsupported,omitempty"`
|
||||||
|
SpecifyIPRanges bool `json:"specifyipranges,omitempty"`
|
||||||
|
SpecifyVlan string `json:"specifyvlan,omitempty"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
SupportedServices string `json:"supportedservices,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
TrafficType string `json:"traffictype,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListNetworkOfferings) name() string {
|
||||||
|
return "listNetworkOfferings"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListNetworkOfferings) response() interface{} {
|
||||||
|
return new(ListNetworkOfferingsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListNetworkOfferingsResponse represents a list of service offerings
|
||||||
|
type ListNetworkOfferingsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
NetworkOffering []NetworkOffering `json:"networkoffering"`
|
||||||
|
}
|
249
vendor/github.com/exoscale/egoscale/networks.go
generated
vendored
Normal file
249
vendor/github.com/exoscale/egoscale/networks.go
generated
vendored
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Network represents a network
|
||||||
|
type Network struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Account string `json:"account"`
|
||||||
|
ACLID string `json:"aclid,omitempty"`
|
||||||
|
ACLType string `json:"acltype,omitempty"`
|
||||||
|
BroadcastDomainType string `json:"broadcastdomaintype,omitempty"`
|
||||||
|
BroadcastURI string `json:"broadcasturi,omitempty"`
|
||||||
|
CanUseForDeploy bool `json:"canusefordeploy,omitempty"`
|
||||||
|
Cidr string `json:"cidr,omitempty"`
|
||||||
|
DisplayNetwork bool `json:"diplaynetwork,omitempty"`
|
||||||
|
DisplayText string `json:"displaytext"`
|
||||||
|
DNS1 net.IP `json:"dns1,omitempty"`
|
||||||
|
DNS2 net.IP `json:"dns2,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Gateway net.IP `json:"gateway,omitempty"`
|
||||||
|
IP6Cidr string `json:"ip6cidr,omitempty"`
|
||||||
|
IP6Gateway net.IP `json:"ip6gateway,omitempty"`
|
||||||
|
IsDefault bool `json:"isdefault,omitempty"`
|
||||||
|
IsPersistent bool `json:"ispersistent,omitempty"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Netmask net.IP `json:"netmask,omitempty"`
|
||||||
|
NetworkCidr string `json:"networkcidr,omitempty"`
|
||||||
|
NetworkDomain string `json:"networkdomain,omitempty"`
|
||||||
|
NetworkOfferingAvailability string `json:"networkofferingavailability,omitempty"`
|
||||||
|
NetworkOfferingConserveMode bool `json:"networkofferingconservemode,omitempty"`
|
||||||
|
NetworkOfferingDisplayText string `json:"networkofferingdisplaytext,omitempty"`
|
||||||
|
NetworkOfferingID string `json:"networkofferingid,omitempty"`
|
||||||
|
NetworkOfferingName string `json:"networkofferingname,omitempty"`
|
||||||
|
PhysicalNetworkID string `json:"physicalnetworkid,omitempty"`
|
||||||
|
Project string `json:"project,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
Related string `json:"related,omitempty"`
|
||||||
|
ReserveIPRange string `json:"reserveiprange,omitempty"`
|
||||||
|
RestartRequired bool `json:"restartrequired,omitempty"`
|
||||||
|
SpecifyIPRanges bool `json:"specifyipranges,omitempty"`
|
||||||
|
State string `json:"state"`
|
||||||
|
StrechedL2Subnet bool `json:"strechedl2subnet,omitempty"`
|
||||||
|
SubdomainAccess bool `json:"subdomainaccess,omitempty"`
|
||||||
|
TrafficType string `json:"traffictype"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Vlan string `json:"vlan,omitemtpy"` // root only
|
||||||
|
VpcID string `json:"vpcid,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
ZoneName string `json:"zonename,omitempty"`
|
||||||
|
ZonesNetworkSpans string `json:"zonesnetworkspans,omitempty"`
|
||||||
|
Service []Service `json:"service"`
|
||||||
|
Tags []ResourceTag `json:"tags"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceType returns the type of the resource
|
||||||
|
func (*Network) ResourceType() string {
|
||||||
|
return "Network"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Service is a feature of a network
|
||||||
|
type Service struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Capability []ServiceCapability `json:"capability,omitempty"`
|
||||||
|
Provider []ServiceProvider `json:"provider,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceCapability represents optional capability of a service
|
||||||
|
type ServiceCapability struct {
|
||||||
|
CanChooseServiceCapability bool `json:"canchooseservicecapability"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceProvider represents the provider of the service
|
||||||
|
type ServiceProvider struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
CanEnableIndividualService bool `json:"canenableindividualservice"`
|
||||||
|
DestinationPhysicalNetworkID string `json:"destinationphysicalnetworkid"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
PhysicalNetworkID string `json:"physicalnetworkid"`
|
||||||
|
ServiceList []string `json:"servicelist,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkResponse represents a network
|
||||||
|
type NetworkResponse struct {
|
||||||
|
Network Network `json:"network"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateNetwork creates a network
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createNetwork.html
|
||||||
|
type CreateNetwork struct {
|
||||||
|
DisplayText string `json:"displaytext,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkOfferingID string `json:"networkofferingid"`
|
||||||
|
ZoneID string `json:"zoneid"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
ACLID string `json:"aclid,omitempty"`
|
||||||
|
ACLType string `json:"acltype,omitempty"` // Account or Domain
|
||||||
|
DisplayNetwork bool `json:"displaynetwork,omitempty"` // root only
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
EndIP net.IP `json:"endip,omitempty"`
|
||||||
|
EndIpv6 net.IP `json:"endipv6,omitempty"`
|
||||||
|
Gateway net.IP `json:"gateway,omitempty"`
|
||||||
|
IP6Cidr string `json:"ip6cidr,omitempty"`
|
||||||
|
IP6Gateway net.IP `json:"ip6gateway,omitempty"`
|
||||||
|
IsolatedPVlan string `json:"isolatedpvlan,omitempty"`
|
||||||
|
Netmask net.IP `json:"netmask,omitempty"`
|
||||||
|
NetworkDomain string `json:"networkdomain,omitempty"`
|
||||||
|
PhysicalNetworkID string `json:"physicalnetworkid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
StartIP net.IP `json:"startip,omitempty"`
|
||||||
|
StartIpv6 net.IP `json:"startipv6,omitempty"`
|
||||||
|
SubdomainAccess string `json:"subdomainaccess,omitempty"`
|
||||||
|
Vlan string `json:"vlan,omitempty"`
|
||||||
|
VpcID string `json:"vpcid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateNetwork) name() string {
|
||||||
|
return "createNetwork"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateNetwork) response() interface{} {
|
||||||
|
return new(CreateNetworkResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req *CreateNetwork) onBeforeSend(params *url.Values) error {
|
||||||
|
// Those fields are required but might be empty
|
||||||
|
if req.Name == "" {
|
||||||
|
params.Set("name", "")
|
||||||
|
}
|
||||||
|
if req.DisplayText == "" {
|
||||||
|
params.Set("displaytext", "")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateNetworkResponse represents a freshly created network
|
||||||
|
type CreateNetworkResponse NetworkResponse
|
||||||
|
|
||||||
|
// UpdateNetwork updates a network
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/updateNetwork.html
|
||||||
|
type UpdateNetwork struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
ChangeCidr bool `json:"changecidr,omitempty"`
|
||||||
|
CustomID string `json:"customid,omitempty"` // root only
|
||||||
|
DisplayNetwork string `json:"displaynetwork,omitempty"`
|
||||||
|
DisplayText string `json:"displaytext,omitempty"`
|
||||||
|
Forced bool `json:"forced,omitempty"`
|
||||||
|
GuestVMCidr string `json:"guestvmcidr,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkDomain string `json:"networkdomain,omitempty"`
|
||||||
|
NetworkOfferingID string `json:"networkofferingid,omitempty"`
|
||||||
|
UpdateInSequence bool `json:"updateinsequence,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateNetwork) name() string {
|
||||||
|
return "updateNetwork"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateNetwork) asyncResponse() interface{} {
|
||||||
|
return new(UpdateNetworkResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNetworkResponse represents a freshly created network
|
||||||
|
type UpdateNetworkResponse NetworkResponse
|
||||||
|
|
||||||
|
// RestartNetwork updates a network
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/restartNetwork.html
|
||||||
|
type RestartNetwork struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Cleanup bool `json:"cleanup,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RestartNetwork) name() string {
|
||||||
|
return "restartNetwork"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RestartNetwork) asyncResponse() interface{} {
|
||||||
|
return new(RestartNetworkResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestartNetworkResponse represents a freshly created network
|
||||||
|
type RestartNetworkResponse NetworkResponse
|
||||||
|
|
||||||
|
// DeleteNetwork deletes a network
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteNetwork.html
|
||||||
|
type DeleteNetwork struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Forced bool `json:"forced,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteNetwork) name() string {
|
||||||
|
return "deleteNetwork"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteNetwork) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListNetworks represents a query to a network
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listNetworks.html
|
||||||
|
type ListNetworks struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
ACLType string `json:"acltype,omitempty"` // Account or Domain
|
||||||
|
CanUseForDeploy bool `json:"canusefordeploy,omitempty"`
|
||||||
|
DisplayNetwork bool `json:"displaynetwork,omitempty"` // root only
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ForVpc string `json:"forvpc,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
IsSystem bool `json:"issystem,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
PhysicalNetworkID string `json:"physicalnetworkid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
RestartRequired bool `json:"restartrequired,omitempty"`
|
||||||
|
SpecifyRanges bool `json:"specifyranges,omitempty"`
|
||||||
|
SupportedServices []Service `json:"supportedservices,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"resourcetag,omitempty"`
|
||||||
|
TrafficType string `json:"traffictype,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
VpcID string `json:"vpcid,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListNetworks) name() string {
|
||||||
|
return "listNetworks"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListNetworks) response() interface{} {
|
||||||
|
return new(ListNetworksResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListNetworksResponse represents the list of networks
|
||||||
|
type ListNetworksResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
Network []Network `json:"network"`
|
||||||
|
}
|
135
vendor/github.com/exoscale/egoscale/nics.go
generated
vendored
Normal file
135
vendor/github.com/exoscale/egoscale/nics.go
generated
vendored
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Nic represents a Network Interface Controller (NIC)
|
||||||
|
type Nic struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
BroadcastURI string `json:"broadcasturi,omitempty"`
|
||||||
|
Gateway net.IP `json:"gateway,omitempty"`
|
||||||
|
IP6Address net.IP `json:"ip6address,omitempty"`
|
||||||
|
IP6Cidr string `json:"ip6cidr,omitempty"`
|
||||||
|
IP6Gateway net.IP `json:"ip6gateway,omitempty"`
|
||||||
|
IPAddress net.IP `json:"ipaddress,omitempty"`
|
||||||
|
IsDefault bool `json:"isdefault,omitempty"`
|
||||||
|
IsolationURI string `json:"isolationuri,omitempty"`
|
||||||
|
MacAddress string `json:"macaddress,omitempty"`
|
||||||
|
Netmask net.IP `json:"netmask,omitempty"`
|
||||||
|
NetworkID string `json:"networkid,omitempty"`
|
||||||
|
NetworkName string `json:"networkname,omitempty"`
|
||||||
|
SecondaryIP []NicSecondaryIP `json:"secondaryip,omitempty"`
|
||||||
|
Traffictype string `json:"traffictype,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
VirtualMachineID string `json:"virtualmachineid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NicSecondaryIP represents a link between NicID and IPAddress
|
||||||
|
type NicSecondaryIP struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
IPAddress net.IP `json:"ipaddress"`
|
||||||
|
NetworkID string `json:"networkid"`
|
||||||
|
NicID string `json:"nicid"`
|
||||||
|
VirtualMachineID string `json:"virtualmachineid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListNics represents the NIC search
|
||||||
|
type ListNics struct {
|
||||||
|
VirtualMachineID string `json:"virtualmachineid"`
|
||||||
|
ForDisplay bool `json:"fordisplay,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
NetworkID string `json:"networkid,omitempty"`
|
||||||
|
NicID string `json:"nicid,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListNics) name() string {
|
||||||
|
return "listNics"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListNics) response() interface{} {
|
||||||
|
return new(ListNicsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListNicsResponse represents a list of templates
|
||||||
|
type ListNicsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
Nic []Nic `json:"nic"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddIPToNic represents the assignation of a secondary IP
|
||||||
|
type AddIPToNic struct {
|
||||||
|
NicID string `json:"nicid"`
|
||||||
|
IPAddress net.IP `json:"ipaddress"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*AddIPToNic) name() string {
|
||||||
|
return "addIpToNic"
|
||||||
|
}
|
||||||
|
func (*AddIPToNic) asyncResponse() interface{} {
|
||||||
|
return new(AddIPToNicResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddIPToNicResponse represents the addition of an IP to a NIC
|
||||||
|
type AddIPToNicResponse struct {
|
||||||
|
NicSecondaryIP NicSecondaryIP `json:"nicsecondaryip"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveIPFromNic represents a deletion request
|
||||||
|
type RemoveIPFromNic struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RemoveIPFromNic) name() string {
|
||||||
|
return "removeIpFromNic"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RemoveIPFromNic) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListNics lists the NIC of a VM
|
||||||
|
//
|
||||||
|
// Deprecated: use the API directly
|
||||||
|
func (exo *Client) ListNics(req *ListNics) ([]Nic, error) {
|
||||||
|
resp, err := exo.Request(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.(*ListNicsResponse).Nic, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddIPToNic adds an IP to a NIC
|
||||||
|
//
|
||||||
|
// Deprecated: use the API directly
|
||||||
|
func (exo *Client) AddIPToNic(nicID string, ipAddress string, async AsyncInfo) (*NicSecondaryIP, error) {
|
||||||
|
ip := net.ParseIP(ipAddress)
|
||||||
|
if ip == nil {
|
||||||
|
return nil, fmt.Errorf("%s is not a valid IP address", ipAddress)
|
||||||
|
}
|
||||||
|
req := &AddIPToNic{
|
||||||
|
NicID: nicID,
|
||||||
|
IPAddress: ip,
|
||||||
|
}
|
||||||
|
resp, err := exo.AsyncRequest(req, async)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nic := resp.(AddIPToNicResponse).NicSecondaryIP
|
||||||
|
return &nic, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveIPFromNic removes an IP from a NIC
|
||||||
|
//
|
||||||
|
// Deprecated: use the API directly
|
||||||
|
func (exo *Client) RemoveIPFromNic(secondaryNicID string, async AsyncInfo) error {
|
||||||
|
req := &RemoveIPFromNic{
|
||||||
|
ID: secondaryNicID,
|
||||||
|
}
|
||||||
|
return exo.BooleanAsyncRequest(req, async)
|
||||||
|
}
|
511
vendor/github.com/exoscale/egoscale/request.go
generated
vendored
511
vendor/github.com/exoscale/egoscale/request.go
generated
vendored
|
@ -1,20 +1,164 @@
|
||||||
package egoscale
|
package egoscale
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Command represent a CloudStack request
|
||||||
|
type Command interface {
|
||||||
|
// CloudStack API command name
|
||||||
|
name() string
|
||||||
|
// Response interface to Unmarshal the JSON into
|
||||||
|
response() interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsyncCommand represents a async CloudStack request
|
||||||
|
type AsyncCommand interface {
|
||||||
|
// CloudStack API command name
|
||||||
|
name() string
|
||||||
|
// Response interface to Unmarshal the JSON into
|
||||||
|
asyncResponse() interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command represents an action to be done on the params before sending them
|
||||||
|
//
|
||||||
|
// This little took helps with issue of relying on JSON serialization logic only.
|
||||||
|
// `omitempty` may make sense in some cases but not all the time.
|
||||||
|
type onBeforeHook interface {
|
||||||
|
onBeforeSend(params *url.Values) error
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Pending represents a job in progress
|
||||||
|
Pending JobStatusType = iota
|
||||||
|
// Success represents a successfully completed job
|
||||||
|
Success
|
||||||
|
// Failure represents a job that has failed to complete
|
||||||
|
Failure
|
||||||
|
)
|
||||||
|
|
||||||
|
// JobStatusType represents the status of a Job
|
||||||
|
type JobStatusType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Unauthorized represents ... (TODO)
|
||||||
|
Unauthorized ErrorCode = 401
|
||||||
|
// MethodNotAllowed represents ... (TODO)
|
||||||
|
MethodNotAllowed = 405
|
||||||
|
// UnsupportedActionError represents ... (TODO)
|
||||||
|
UnsupportedActionError = 422
|
||||||
|
// APILimitExceeded represents ... (TODO)
|
||||||
|
APILimitExceeded = 429
|
||||||
|
// MalformedParameterError represents ... (TODO)
|
||||||
|
MalformedParameterError = 430
|
||||||
|
// ParamError represents ... (TODO)
|
||||||
|
ParamError = 431
|
||||||
|
|
||||||
|
// InternalError represents a server error
|
||||||
|
InternalError = 530
|
||||||
|
// AccountError represents ... (TODO)
|
||||||
|
AccountError = 531
|
||||||
|
// AccountResourceLimitError represents ... (TODO)
|
||||||
|
AccountResourceLimitError = 532
|
||||||
|
// InsufficientCapacityError represents ... (TODO)
|
||||||
|
InsufficientCapacityError = 533
|
||||||
|
// ResourceUnavailableError represents ... (TODO)
|
||||||
|
ResourceUnavailableError = 534
|
||||||
|
// ResourceAllocationError represents ... (TODO)
|
||||||
|
ResourceAllocationError = 535
|
||||||
|
// ResourceInUseError represents ... (TODO)
|
||||||
|
ResourceInUseError = 536
|
||||||
|
// NetworkRuleConflictError represents ... (TODO)
|
||||||
|
NetworkRuleConflictError = 537
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrorCode represents the CloudStack ApiErrorCode enum
|
||||||
|
//
|
||||||
|
// See: https://github.com/apache/cloudstack/blob/master/api/src/org/apache/cloudstack/api/ApiErrorCode.java
|
||||||
|
type ErrorCode int
|
||||||
|
|
||||||
|
// JobResultResponse represents a generic response to a job task
|
||||||
|
type JobResultResponse struct {
|
||||||
|
AccountID string `json:"accountid,omitempty"`
|
||||||
|
Cmd string `json:"cmd"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
JobID string `json:"jobid"`
|
||||||
|
JobProcStatus int `json:"jobprocstatus"`
|
||||||
|
JobResult *json.RawMessage `json:"jobresult"`
|
||||||
|
JobStatus JobStatusType `json:"jobstatus"`
|
||||||
|
JobResultType string `json:"jobresulttype"`
|
||||||
|
UserID string `json:"userid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorResponse represents the standard error response from CloudStack
|
||||||
|
type ErrorResponse struct {
|
||||||
|
ErrorCode ErrorCode `json:"errorcode"`
|
||||||
|
CsErrorCode int `json:"cserrorcode"`
|
||||||
|
ErrorText string `json:"errortext"`
|
||||||
|
UUIDList []string `json:"uuidList,omitempty"` // uuid*L*ist is not a typo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error formats a CloudStack error into a standard error
|
||||||
|
func (e *ErrorResponse) Error() string {
|
||||||
|
return fmt.Sprintf("API error %d (internal code: %d): %s", e.ErrorCode, e.CsErrorCode, e.ErrorText)
|
||||||
|
}
|
||||||
|
|
||||||
|
// booleanAsyncResponse represents a boolean response (usually after a deletion)
|
||||||
|
type booleanAsyncResponse struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
DisplayText string `json:"diplaytext,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error formats a CloudStack job response into a standard error
|
||||||
|
func (e *booleanAsyncResponse) Error() error {
|
||||||
|
if e.Success {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("API error: %s", e.DisplayText)
|
||||||
|
}
|
||||||
|
|
||||||
|
// booleanAsyncResponse represents a boolean response for sync calls
|
||||||
|
type booleanSyncResponse struct {
|
||||||
|
Success string `json:"success"`
|
||||||
|
DisplayText string `json:"displaytext,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *booleanSyncResponse) Error() error {
|
||||||
|
if e.Success == "true" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("API error: %s", e.DisplayText)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsyncInfo represents the details for any async call
|
||||||
|
//
|
||||||
|
// It retries at most Retries time and waits for Delay between each retry
|
||||||
|
type AsyncInfo struct {
|
||||||
|
Retries int
|
||||||
|
Delay int
|
||||||
|
}
|
||||||
|
|
||||||
func csQuotePlus(s string) string {
|
func csQuotePlus(s string) string {
|
||||||
return strings.Replace(s, "+", "%20", -1)
|
s = strings.Replace(s, "+", "%20", -1)
|
||||||
|
s = strings.Replace(s, "%5B", "[", -1)
|
||||||
|
s = strings.Replace(s, "%5D", "]", -1)
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func csEncode(s string) string {
|
func csEncode(s string) string {
|
||||||
|
@ -43,7 +187,7 @@ func rawValues(b json.RawMessage) (json.RawMessage, error) {
|
||||||
return i[0], nil
|
return i[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (exo *Client) ParseResponse(resp *http.Response) (json.RawMessage, error) {
|
func (exo *Client) parseResponse(resp *http.Response) (json.RawMessage, error) {
|
||||||
b, err := ioutil.ReadAll(resp.Body)
|
b, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -59,75 +203,362 @@ func (exo *Client) ParseResponse(resp *http.Response) (json.RawMessage, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode >= 400 {
|
if resp.StatusCode >= 400 {
|
||||||
var e Error
|
var e ErrorResponse
|
||||||
if err := json.Unmarshal(b, &e); err != nil {
|
if err := json.Unmarshal(b, &e); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return b, &e
|
||||||
/* Need to account for differet error types */
|
|
||||||
if e.ErrorCode != 0 {
|
|
||||||
return nil, e.Error()
|
|
||||||
} else {
|
|
||||||
var de DNSError
|
|
||||||
if err := json.Unmarshal(b, &de); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("Exoscale error (%d): %s", resp.StatusCode, strings.Join(de.Name, "\n"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (exo *Client) Request(command string, params url.Values) (json.RawMessage, error) {
|
// AsyncRequest performs an asynchronous request and polls it for retries * day [s]
|
||||||
|
func (exo *Client) AsyncRequest(req AsyncCommand, async AsyncInfo) (interface{}, error) {
|
||||||
|
body, err := exo.request(req.name(), req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
mac := hmac.New(sha1.New, []byte(exo.apiSecret))
|
// Is it a Job?
|
||||||
keys := make([]string, 0)
|
job := new(JobResultResponse)
|
||||||
unencoded := make([]string, 0)
|
if err := json.Unmarshal(body, &job); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error response
|
||||||
|
errorResponse := new(ErrorResponse)
|
||||||
|
// Successful response
|
||||||
|
resp := req.asyncResponse()
|
||||||
|
if job.JobID == "" || job.JobStatus != Pending {
|
||||||
|
if err := json.Unmarshal(*job.JobResult, resp); err != nil {
|
||||||
|
return job, err
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// we've got a pending job
|
||||||
|
result := &QueryAsyncJobResultResponse{
|
||||||
|
JobStatus: job.JobStatus,
|
||||||
|
}
|
||||||
|
for async.Retries > 0 && result.JobStatus == Pending {
|
||||||
|
time.Sleep(time.Duration(async.Delay) * time.Second)
|
||||||
|
|
||||||
|
async.Retries--
|
||||||
|
|
||||||
|
req := &QueryAsyncJobResult{JobID: job.JobID}
|
||||||
|
resp, err := exo.Request(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result = resp.(*QueryAsyncJobResultResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.JobStatus == Failure {
|
||||||
|
if err := json.Unmarshal(*result.JobResult, &errorResponse); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return errorResponse, errorResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.JobStatus == Pending {
|
||||||
|
return result, fmt.Errorf("Maximum number of retries reached")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(*result.JobResult, resp); err != nil {
|
||||||
|
if err := json.Unmarshal(*result.JobResult, errorResponse); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return errorResponse, errorResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BooleanRequest performs a sync request on a boolean call
|
||||||
|
func (exo *Client) BooleanRequest(req Command) error {
|
||||||
|
resp, err := exo.Request(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.(*booleanSyncResponse).Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BooleanAsyncRequest performs a sync request on a boolean call
|
||||||
|
func (exo *Client) BooleanAsyncRequest(req AsyncCommand, async AsyncInfo) error {
|
||||||
|
resp, err := exo.AsyncRequest(req, async)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.(*booleanAsyncResponse).Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request performs a sync request on a generic command
|
||||||
|
func (exo *Client) Request(req Command) (interface{}, error) {
|
||||||
|
body, err := exo.request(req.name(), req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := req.response()
|
||||||
|
if err := json.Unmarshal(body, resp); err != nil {
|
||||||
|
r := new(ErrorResponse)
|
||||||
|
if e := json.Unmarshal(body, r); e != nil {
|
||||||
|
return nil, r
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// request makes a Request while being close to the metal
|
||||||
|
func (exo *Client) request(command string, req interface{}) (json.RawMessage, error) {
|
||||||
|
params := url.Values{}
|
||||||
|
err := prepareValues("", ¶ms, req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if hookReq, ok := req.(onBeforeHook); ok {
|
||||||
|
hookReq.onBeforeSend(¶ms)
|
||||||
|
}
|
||||||
params.Set("apikey", exo.apiKey)
|
params.Set("apikey", exo.apiKey)
|
||||||
params.Set("command", command)
|
params.Set("command", command)
|
||||||
params.Set("response", "json")
|
params.Set("response", "json")
|
||||||
|
|
||||||
for k, _ := range params {
|
// This code is borrowed from net/url/url.go
|
||||||
|
// The way it's encoded by net/url doesn't match
|
||||||
|
// how CloudStack works.
|
||||||
|
var buf bytes.Buffer
|
||||||
|
keys := make([]string, 0, len(params))
|
||||||
|
for k := range params {
|
||||||
keys = append(keys, k)
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
arg := k + "=" + csEncode(params[k][0])
|
prefix := csEncode(k) + "="
|
||||||
unencoded = append(unencoded, arg)
|
for _, v := range params[k] {
|
||||||
|
if buf.Len() > 0 {
|
||||||
|
buf.WriteByte('&')
|
||||||
|
}
|
||||||
|
buf.WriteString(prefix)
|
||||||
|
buf.WriteString(csEncode(v))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sign_string := strings.ToLower(strings.Join(unencoded, "&"))
|
|
||||||
|
|
||||||
mac.Write([]byte(sign_string))
|
query := buf.String()
|
||||||
|
|
||||||
|
mac := hmac.New(sha1.New, []byte(exo.apiSecret))
|
||||||
|
mac.Write([]byte(strings.ToLower(query)))
|
||||||
signature := csEncode(base64.StdEncoding.EncodeToString(mac.Sum(nil)))
|
signature := csEncode(base64.StdEncoding.EncodeToString(mac.Sum(nil)))
|
||||||
query := params.Encode()
|
|
||||||
url := exo.endpoint + "?" + csQuotePlus(query) + "&signature=" + signature
|
|
||||||
|
|
||||||
resp, err := exo.client.Get(url)
|
reader := strings.NewReader(fmt.Sprintf("%s&signature=%s", csQuotePlus(query), signature))
|
||||||
|
resp, err := exo.client.Post(exo.endpoint, "application/x-www-form-urlencoded", reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
return exo.ParseResponse(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) DetailedRequest(uri string, params string, method string, header http.Header) (json.RawMessage, error) {
|
body, err := exo.parseResponse(resp)
|
||||||
url := exo.endpoint + uri
|
|
||||||
|
|
||||||
req, err := http.NewRequest(method, url, strings.NewReader(params))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header = header
|
return body, nil
|
||||||
|
}
|
||||||
|
|
||||||
response, err := exo.client.Do(req)
|
// prepareValues uses a command to build a POST request
|
||||||
if err != nil {
|
//
|
||||||
return nil, err
|
// command is not a Command so it's easier to Test
|
||||||
|
func prepareValues(prefix string, params *url.Values, command interface{}) error {
|
||||||
|
value := reflect.ValueOf(command)
|
||||||
|
typeof := reflect.TypeOf(command)
|
||||||
|
// Going up the pointer chain to find the underlying struct
|
||||||
|
for typeof.Kind() == reflect.Ptr {
|
||||||
|
typeof = typeof.Elem()
|
||||||
|
value = value.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
defer response.Body.Close()
|
for i := 0; i < typeof.NumField(); i++ {
|
||||||
return exo.ParseResponse(response)
|
field := typeof.Field(i)
|
||||||
|
val := value.Field(i)
|
||||||
|
tag := field.Tag
|
||||||
|
if json, ok := tag.Lookup("json"); ok {
|
||||||
|
n, required := extractJSONTag(field.Name, json)
|
||||||
|
name := prefix + n
|
||||||
|
|
||||||
|
switch val.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
v := val.Int()
|
||||||
|
if v == 0 {
|
||||||
|
if required {
|
||||||
|
return fmt.Errorf("%s.%s (%v) is required, got 0", typeof.Name(), field.Name, val.Kind())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(*params).Set(name, strconv.FormatInt(v, 10))
|
||||||
|
}
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
v := val.Uint()
|
||||||
|
if v == 0 {
|
||||||
|
if required {
|
||||||
|
return fmt.Errorf("%s.%s (%v) is required, got 0", typeof.Name(), field.Name, val.Kind())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(*params).Set(name, strconv.FormatUint(v, 10))
|
||||||
|
}
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
v := val.Float()
|
||||||
|
if v == 0 {
|
||||||
|
if required {
|
||||||
|
return fmt.Errorf("%s.%s (%v) is required, got 0", typeof.Name(), field.Name, val.Kind())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(*params).Set(name, strconv.FormatFloat(v, 'f', -1, 64))
|
||||||
|
}
|
||||||
|
case reflect.String:
|
||||||
|
v := val.String()
|
||||||
|
if v == "" {
|
||||||
|
if required {
|
||||||
|
return fmt.Errorf("%s.%s (%v) is required, got \"\"", typeof.Name(), field.Name, val.Kind())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(*params).Set(name, v)
|
||||||
|
}
|
||||||
|
case reflect.Bool:
|
||||||
|
v := val.Bool()
|
||||||
|
if v == false {
|
||||||
|
if required {
|
||||||
|
params.Set(name, "false")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(*params).Set(name, "true")
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
switch field.Type.Elem().Kind() {
|
||||||
|
case reflect.Uint8:
|
||||||
|
switch field.Type {
|
||||||
|
case reflect.TypeOf(net.IPv4zero):
|
||||||
|
ip := (net.IP)(val.Bytes())
|
||||||
|
if ip == nil || ip.Equal(net.IPv4zero) {
|
||||||
|
if required {
|
||||||
|
return fmt.Errorf("%s.%s (%v) is required, got zero IPv4 address", typeof.Name(), field.Name, val.Kind())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(*params).Set(name, ip.String())
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if val.Len() == 0 {
|
||||||
|
if required {
|
||||||
|
return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), field.Name, val.Kind())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v := val.Bytes()
|
||||||
|
(*params).Set(name, base64.StdEncoding.EncodeToString(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.String:
|
||||||
|
{
|
||||||
|
if val.Len() == 0 {
|
||||||
|
if required {
|
||||||
|
return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), field.Name, val.Kind())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
elems := make([]string, 0, val.Len())
|
||||||
|
for i := 0; i < val.Len(); i++ {
|
||||||
|
// XXX what if the value contains a comma? Double encode?
|
||||||
|
s := val.Index(i).String()
|
||||||
|
elems = append(elems, s)
|
||||||
|
}
|
||||||
|
(*params).Set(name, strings.Join(elems, ","))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if val.Len() == 0 {
|
||||||
|
if required {
|
||||||
|
return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), field.Name, val.Kind())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := prepareList(name, params, val.Interface())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Map:
|
||||||
|
if val.Len() == 0 {
|
||||||
|
if required {
|
||||||
|
return fmt.Errorf("%s.%s (%v) is required, got empty map", typeof.Name(), field.Name, val.Kind())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := prepareMap(name, params, val.Interface())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if required {
|
||||||
|
return fmt.Errorf("Unsupported type %s.%s (%v)", typeof.Name(), field.Name, val.Kind())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Printf("[SKIP] %s.%s no json label found", typeof.Name(), field.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareList(prefix string, params *url.Values, slice interface{}) error {
|
||||||
|
value := reflect.ValueOf(slice)
|
||||||
|
|
||||||
|
for i := 0; i < value.Len(); i++ {
|
||||||
|
prepareValues(fmt.Sprintf("%s[%d].", prefix, i), params, value.Index(i).Interface())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareMap(prefix string, params *url.Values, m interface{}) error {
|
||||||
|
value := reflect.ValueOf(m)
|
||||||
|
|
||||||
|
for i, key := range value.MapKeys() {
|
||||||
|
var keyName string
|
||||||
|
var keyValue string
|
||||||
|
|
||||||
|
switch key.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
keyName = key.String()
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Only map[string]string are supported (XXX)")
|
||||||
|
}
|
||||||
|
|
||||||
|
val := value.MapIndex(key)
|
||||||
|
switch val.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
keyValue = val.String()
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Only map[string]string are supported (XXX)")
|
||||||
|
}
|
||||||
|
params.Set(fmt.Sprintf("%s[%d].%s", prefix, i, keyName), keyValue)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractJSONTag returns the variable name or defaultName as well as if the field is required (!omitempty)
|
||||||
|
func extractJSONTag(defaultName, jsonTag string) (string, bool) {
|
||||||
|
tags := strings.Split(jsonTag, ",")
|
||||||
|
name := tags[0]
|
||||||
|
required := true
|
||||||
|
for _, tag := range tags {
|
||||||
|
if tag == "omitempty" {
|
||||||
|
required = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if name == "" || name == "omitempty" {
|
||||||
|
name = defaultName
|
||||||
|
}
|
||||||
|
return name, required
|
||||||
}
|
}
|
||||||
|
|
302
vendor/github.com/exoscale/egoscale/security_groups.go
generated
vendored
Normal file
302
vendor/github.com/exoscale/egoscale/security_groups.go
generated
vendored
Normal file
|
@ -0,0 +1,302 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SecurityGroup represent a firewalling set of rules
|
||||||
|
type SecurityGroup struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Project string `json:"project,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
VirtualMachineCount int `json:"virtualmachinecount,omitempty"` // CloudStack 4.6+
|
||||||
|
VirtualMachineIDs []string `json:"virtualmachineids,omitempty"` // CloudStack 4.6+
|
||||||
|
IngressRule []IngressRule `json:"ingressrule"`
|
||||||
|
EgressRule []EgressRule `json:"egressrule"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
JobID string `json:"jobid,omitempty"`
|
||||||
|
JobStatus JobStatusType `json:"jobstatus,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceType returns the type of the resource
|
||||||
|
func (*SecurityGroup) ResourceType() string {
|
||||||
|
return "SecurityGroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
// IngressRule represents the ingress rule
|
||||||
|
type IngressRule struct {
|
||||||
|
RuleID string `json:"ruleid"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
Cidr string `json:"cidr,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
IcmpType int `json:"icmptype,omitempty"`
|
||||||
|
IcmpCode int `json:"icmpcode,omitempty"`
|
||||||
|
StartPort int `json:"startport,omitempty"`
|
||||||
|
EndPort int `json:"endport,omitempty"`
|
||||||
|
Protocol string `json:"protocol,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
SecurityGroupID string `json:"securitygroupid,omitempty"`
|
||||||
|
SecurityGroupName string `json:"securitygroupname,omitempty"`
|
||||||
|
UserSecurityGroupList []UserSecurityGroup `json:"usersecuritygrouplist,omitempty"`
|
||||||
|
JobID string `json:"jobid,omitempty"`
|
||||||
|
JobStatus JobStatusType `json:"jobstatus,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EgressRule represents the ingress rule
|
||||||
|
type EgressRule IngressRule
|
||||||
|
|
||||||
|
// UserSecurityGroup represents the traffic of another security group
|
||||||
|
type UserSecurityGroup struct {
|
||||||
|
Group string `json:"group,omitempty"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecurityGroupResponse represents a generic security group response
|
||||||
|
type SecurityGroupResponse struct {
|
||||||
|
SecurityGroup SecurityGroup `json:"securitygroup"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSecurityGroup represents a security group creation
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/createSecurityGroup.html
|
||||||
|
type CreateSecurityGroup struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateSecurityGroup) name() string {
|
||||||
|
return "createSecurityGroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateSecurityGroup) response() interface{} {
|
||||||
|
return new(CreateSecurityGroupResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSecurityGroupResponse represents a new security group
|
||||||
|
type CreateSecurityGroupResponse SecurityGroupResponse
|
||||||
|
|
||||||
|
// DeleteSecurityGroup represents a security group deletion
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/deleteSecurityGroup.html
|
||||||
|
type DeleteSecurityGroup struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"` // Mutually exclusive with name
|
||||||
|
Name string `json:"name,omitempty"` // Mutually exclusive with id
|
||||||
|
ProjectID string `json:"project,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteSecurityGroup) name() string {
|
||||||
|
return "deleteSecurityGroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteSecurityGroup) response() interface{} {
|
||||||
|
return new(booleanSyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthorizeSecurityGroupIngress (Async) represents the ingress rule creation
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/authorizeSecurityGroupIngress.html
|
||||||
|
type AuthorizeSecurityGroupIngress struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
CidrList []string `json:"cidrlist,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
IcmpType int `json:"icmptype,omitempty"`
|
||||||
|
IcmpCode int `json:"icmpcode,omitempty"`
|
||||||
|
StartPort int `json:"startport,omitempty"`
|
||||||
|
EndPort int `json:"endport,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
Protocol string `json:"protocol,omitempty"`
|
||||||
|
SecurityGroupID string `json:"securitygroupid,omitempty"`
|
||||||
|
SecurityGroupName string `json:"securitygroupname,omitempty"`
|
||||||
|
UserSecurityGroupList []UserSecurityGroup `json:"usersecuritygrouplist,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*AuthorizeSecurityGroupIngress) name() string {
|
||||||
|
return "authorizeSecurityGroupIngress"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*AuthorizeSecurityGroupIngress) asyncResponse() interface{} {
|
||||||
|
return new(AuthorizeSecurityGroupIngressResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req *AuthorizeSecurityGroupIngress) onBeforeSend(params *url.Values) error {
|
||||||
|
// ICMP code and type may be zero but can also be omitted...
|
||||||
|
if req.Protocol == "ICMP" {
|
||||||
|
params.Set("icmpcode", strconv.FormatInt(int64(req.IcmpCode), 10))
|
||||||
|
params.Set("icmptype", strconv.FormatInt(int64(req.IcmpType), 10))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthorizeSecurityGroupIngressResponse represents the new egress rule
|
||||||
|
// /!\ the Cloud Stack API document is not fully accurate. /!\
|
||||||
|
type AuthorizeSecurityGroupIngressResponse SecurityGroupResponse
|
||||||
|
|
||||||
|
// AuthorizeSecurityGroupEgress (Async) represents the egress rule creation
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/authorizeSecurityGroupEgress.html
|
||||||
|
type AuthorizeSecurityGroupEgress AuthorizeSecurityGroupIngress
|
||||||
|
|
||||||
|
func (*AuthorizeSecurityGroupEgress) name() string {
|
||||||
|
return "authorizeSecurityGroupEgress"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*AuthorizeSecurityGroupEgress) asyncResponse() interface{} {
|
||||||
|
return new(AuthorizeSecurityGroupEgressResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (req *AuthorizeSecurityGroupEgress) onBeforeSend(params *url.Values) error {
|
||||||
|
return (*AuthorizeSecurityGroupIngress)(req).onBeforeSend(params)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthorizeSecurityGroupEgressResponse represents the new egress rule
|
||||||
|
// /!\ the Cloud Stack API document is not fully accurate. /!\
|
||||||
|
type AuthorizeSecurityGroupEgressResponse CreateSecurityGroupResponse
|
||||||
|
|
||||||
|
// RevokeSecurityGroupIngress (Async) represents the ingress/egress rule deletion
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/revokeSecurityGroupIngress.html
|
||||||
|
type RevokeSecurityGroupIngress struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RevokeSecurityGroupIngress) name() string {
|
||||||
|
return "revokeSecurityGroupIngress"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RevokeSecurityGroupIngress) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RevokeSecurityGroupEgress (Async) represents the ingress/egress rule deletion
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/revokeSecurityGroupEgress.html
|
||||||
|
type RevokeSecurityGroupEgress struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RevokeSecurityGroupEgress) name() string {
|
||||||
|
return "revokeSecurityGroupEgress"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RevokeSecurityGroupEgress) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListSecurityGroups represents a search for security groups
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listSecurityGroups.html
|
||||||
|
type ListSecurityGroups struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
SecurityGroupName string `json:"securitygroupname,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
VirtualMachineID string `json:"virtualmachineid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListSecurityGroups) name() string {
|
||||||
|
return "listSecurityGroups"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListSecurityGroups) response() interface{} {
|
||||||
|
return new(ListSecurityGroupsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListSecurityGroupsResponse represents a list of security groups
|
||||||
|
type ListSecurityGroupsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
SecurityGroup []SecurityGroup `json:"securitygroup"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateIngressRule creates a set of ingress rules
|
||||||
|
//
|
||||||
|
// Deprecated: use the API directly
|
||||||
|
func (exo *Client) CreateIngressRule(req *AuthorizeSecurityGroupIngress, async AsyncInfo) ([]IngressRule, error) {
|
||||||
|
resp, err := exo.AsyncRequest(req, async)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp.(*AuthorizeSecurityGroupIngressResponse).SecurityGroup.IngressRule, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateEgressRule creates a set of egress rules
|
||||||
|
//
|
||||||
|
// Deprecated: use the API directly
|
||||||
|
func (exo *Client) CreateEgressRule(req *AuthorizeSecurityGroupEgress, async AsyncInfo) ([]EgressRule, error) {
|
||||||
|
resp, err := exo.AsyncRequest(req, async)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp.(*AuthorizeSecurityGroupEgressResponse).SecurityGroup.EgressRule, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSecurityGroupWithRules create a security group with its rules
|
||||||
|
// Warning: it doesn't rollback in case of a failure!
|
||||||
|
//
|
||||||
|
// Deprecated: use the API directly
|
||||||
|
func (exo *Client) CreateSecurityGroupWithRules(name string, ingress []AuthorizeSecurityGroupIngress, egress []AuthorizeSecurityGroupEgress, async AsyncInfo) (*SecurityGroup, error) {
|
||||||
|
req := &CreateSecurityGroup{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
resp, err := exo.Request(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sg := resp.(*SecurityGroupResponse).SecurityGroup
|
||||||
|
reqs := make([]AsyncCommand, 0, len(ingress)+len(egress))
|
||||||
|
// Egress rules
|
||||||
|
for _, ereq := range egress {
|
||||||
|
ereq.SecurityGroupID = sg.ID
|
||||||
|
reqs = append(reqs, &ereq)
|
||||||
|
|
||||||
|
}
|
||||||
|
// Ingress rules
|
||||||
|
for _, ireq := range ingress {
|
||||||
|
ireq.SecurityGroupID = sg.ID
|
||||||
|
reqs = append(reqs, &ireq)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, r := range reqs {
|
||||||
|
_, err := exo.AsyncRequest(r, async)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := exo.Request(&ListSecurityGroups{
|
||||||
|
ID: sg.ID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sg = r.(*ListSecurityGroupsResponse).SecurityGroup[0]
|
||||||
|
return &sg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSecurityGroup deletes a security group
|
||||||
|
//
|
||||||
|
// Deprecated: use the API directly
|
||||||
|
func (exo *Client) DeleteSecurityGroup(name string) error {
|
||||||
|
req := &DeleteSecurityGroup{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
return exo.BooleanRequest(req)
|
||||||
|
}
|
65
vendor/github.com/exoscale/egoscale/service_offerings.go
generated
vendored
Normal file
65
vendor/github.com/exoscale/egoscale/service_offerings.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// ServiceOffering corresponds to the Compute Offerings
|
||||||
|
type ServiceOffering struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
CPUNumber int `json:"cpunumber"`
|
||||||
|
CPUSpeed int `json:"cpuspeed"`
|
||||||
|
Created string `json:"created"`
|
||||||
|
DefaultUse bool `json:"defaultuse,omitempty"`
|
||||||
|
DeploymentPlanner string `json:"deploymentplanner,omitempty"`
|
||||||
|
DiskBytesReadRate int64 `json:"diskBytesReadRate,omitempty"`
|
||||||
|
DiskBytesWriteRate int64 `json:"diskBytesWriteRate,omitempty"`
|
||||||
|
DiskIopsReadRate int64 `json:"diskIopsReadRate,omitempty"`
|
||||||
|
DiskIopsWriteRate int64 `json:"diskIopsWriteRate,omitempty"`
|
||||||
|
DisplayText string `json:"displaytext,omitempty"`
|
||||||
|
Domain string `json:"domain"`
|
||||||
|
DomainID string `json:"domainid"`
|
||||||
|
HostTags string `json:"hosttags,omitempty"`
|
||||||
|
HypervisorSnapshotReserve int `json:"hypervisorsnapshotreserve,omitempty"`
|
||||||
|
IsCustomized bool `json:"iscustomized,omitempty"`
|
||||||
|
IsCustomizedIops bool `json:"iscustomizediops,omitempty"`
|
||||||
|
IsSystem bool `json:"issystem,omitempty"`
|
||||||
|
IsVolatile bool `json:"isvolatile,omitempty"`
|
||||||
|
LimitCPUUse bool `json:"limitcpuuse,omitempty"`
|
||||||
|
MaxIops int64 `json:"maxiops,omitempty"`
|
||||||
|
Memory int `json:"memory,omitempty"`
|
||||||
|
MinIops int64 `json:"miniops,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkRate int `json:"networkrate,omitempty"`
|
||||||
|
OfferHA bool `json:"offerha,omitempty"`
|
||||||
|
ServiceOfferingDetails map[string]string `json:"serviceofferingdetails,omitempty"`
|
||||||
|
StorageType string `json:"storagetype,omitempty"`
|
||||||
|
SystemVMType string `json:"systemvmtype,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListServiceOfferings represents a query for service offerings
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listServiceOfferings.html
|
||||||
|
type ListServiceOfferings struct {
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
IsSystem bool `json:"issystem,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
SystemVMType string `json:"systemvmtype,omitempty"` // consoleproxy, secondarystoragevm, or domainrouter
|
||||||
|
VirtualMachineID string `json:"virtualmachineid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListServiceOfferings) name() string {
|
||||||
|
return "listServiceOfferings"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListServiceOfferings) response() interface{} {
|
||||||
|
return new(ListServiceOfferingsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListServiceOfferingsResponse represents a list of service offerings
|
||||||
|
type ListServiceOfferingsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
ServiceOffering []ServiceOffering `json:"serviceoffering"`
|
||||||
|
}
|
120
vendor/github.com/exoscale/egoscale/snapshots.go
generated
vendored
Normal file
120
vendor/github.com/exoscale/egoscale/snapshots.go
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// Snapshot represents a volume snapshot
|
||||||
|
type Snapshot struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Account string `json:"account"`
|
||||||
|
Created string `json:"created,omitempty"`
|
||||||
|
Domain string `json:"domain"`
|
||||||
|
DomainID string `json:"domainid"`
|
||||||
|
IntervalType string `json:"intervaltype,omitempty"` // hourly, daily, weekly, monthly, ..., none
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
PhysicalSize int64 `json:"physicalsize"`
|
||||||
|
Project string `json:"project"`
|
||||||
|
ProjectID string `json:"projectid"`
|
||||||
|
Revertable bool `json:"revertable,omitempty"`
|
||||||
|
Size int64 `json:"size,omitempty"`
|
||||||
|
SnapshotType string `json:"snapshottype,omitempty"`
|
||||||
|
State string `json:"state"` // BackedUp, Creating, BackingUp, ...
|
||||||
|
VolumeID string `json:"volumeid"`
|
||||||
|
VolumeName string `json:"volumename,omitempty"`
|
||||||
|
VolumeType string `json:"volumetype,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid"`
|
||||||
|
Tags []ResourceTag `json:"tags"`
|
||||||
|
JobID string `json:"jobid,omitempty"`
|
||||||
|
JobStatus JobStatusType `json:"jobstatus,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceType returns the type of the resource
|
||||||
|
func (*Snapshot) ResourceType() string {
|
||||||
|
return "Snapshot"
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSnapshot represents a request to create a volume snapshot
|
||||||
|
//
|
||||||
|
// CloudStackAPI: http://cloudstack.apache.org/api/apidocs-4.10/apis/createSnapshot.html
|
||||||
|
type CreateSnapshot struct {
|
||||||
|
VolumeID string `json:"volumeid"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
PolicyID string `json:"policyid,omitempty"`
|
||||||
|
QuiesceVM bool `json:"quiescevm,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateSnapshot) name() string {
|
||||||
|
return "createSnapshot"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateSnapshot) asyncResponse() interface{} {
|
||||||
|
return new(CreateSnapshotResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSnapshotResponse represents a freshly created snapshot
|
||||||
|
type CreateSnapshotResponse struct {
|
||||||
|
Snapshot Snapshot `json:"snapshot"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListSnapshots lists the volume snapshots
|
||||||
|
//
|
||||||
|
// CloudStackAPI: http://cloudstack.apache.org/api/apidocs-4.10/apis/listSnapshots.html
|
||||||
|
type ListSnapshots struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IntervalType string `json:"intervaltype,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
SnapshotType string `json:"snapshottype,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
VolumeID string `json:"volumeid,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListSnapshots) name() string {
|
||||||
|
return "listSnapshots"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListSnapshots) response() interface{} {
|
||||||
|
return new(ListSnapshotsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListSnapshotsResponse represents a list of volume snapshots
|
||||||
|
type ListSnapshotsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
Snapshot []Snapshot `json:"snapshot"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteSnapshot represents the deletion of a volume snapshot
|
||||||
|
//
|
||||||
|
// CloudStackAPI: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteSnapshot.html
|
||||||
|
type DeleteSnapshot struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteSnapshot) name() string {
|
||||||
|
return "deleteSnapshot"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteSnapshot) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RevertSnapshot revert a volume snapshot
|
||||||
|
//
|
||||||
|
// CloudStackAPI: http://cloudstack.apache.org/api/apidocs-4.10/apis/revertSnapshot.html
|
||||||
|
type RevertSnapshot struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RevertSnapshot) name() string {
|
||||||
|
return "revertSnapshot"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RevertSnapshot) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
93
vendor/github.com/exoscale/egoscale/tags.go
generated
vendored
Normal file
93
vendor/github.com/exoscale/egoscale/tags.go
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// Taggable represents a resource which can have tags attached
|
||||||
|
//
|
||||||
|
// This is a helper to fill the resourcetype of a CreateTags call
|
||||||
|
type Taggable interface {
|
||||||
|
// CloudStack resource type of the Taggable type
|
||||||
|
ResourceType() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceTag is a tag associated with a resource
|
||||||
|
//
|
||||||
|
// http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/4.9/management.html
|
||||||
|
type ResourceTag struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
Customer string `json:"customer,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
Project string `json:"project,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
ResourceID string `json:"resourceid,omitempty"`
|
||||||
|
ResourceType string `json:"resourcetype,omitempty"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTags (Async) creates resource tag(s)
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createTags.html
|
||||||
|
type CreateTags struct {
|
||||||
|
ResourceIDs []string `json:"resourceids"`
|
||||||
|
ResourceType string `json:"resourcetype"`
|
||||||
|
Tags []ResourceTag `json:"tags"`
|
||||||
|
Customer string `json:"customer,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateTags) name() string {
|
||||||
|
return "createTags"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateTags) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteTags (Async) deletes the resource tag(s)
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteTags.html
|
||||||
|
type DeleteTags struct {
|
||||||
|
ResourceIDs []string `json:"resourceids"`
|
||||||
|
ResourceType string `json:"resourcetype"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteTags) name() string {
|
||||||
|
return "deleteTags"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteTags) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTags list resource tag(s)
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listTags.html
|
||||||
|
type ListTags struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
Customer string `json:"customer,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Key string `json:"key,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
ResourceID string `json:"resourceid,omitempty"`
|
||||||
|
ResourceType string `json:"resourcetype,omitempty"`
|
||||||
|
Value string `json:"value,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListTags) name() string {
|
||||||
|
return "listTags"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListTags) response() interface{} {
|
||||||
|
return new(ListTagsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTagsResponse represents a list of resource tags
|
||||||
|
type ListTagsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
Tag []ResourceTag `json:"tag"`
|
||||||
|
}
|
76
vendor/github.com/exoscale/egoscale/templates.go
generated
vendored
Normal file
76
vendor/github.com/exoscale/egoscale/templates.go
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// Template represents a machine to be deployed
|
||||||
|
type Template struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
AccountID string `json:"accountid,omitempty"`
|
||||||
|
Bootable bool `json:"bootable,omitempty"`
|
||||||
|
Checksum string `json:"checksum,omitempty"`
|
||||||
|
Created string `json:"created,omitempty"`
|
||||||
|
CrossZones bool `json:"crossZones,omitempty"`
|
||||||
|
Details map[string]string `json:"details,omitempty"`
|
||||||
|
DisplayText string `json:"displaytext,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Format string `json:"format,omitempty"`
|
||||||
|
HostID string `json:"hostid,omitempty"`
|
||||||
|
HostName string `json:"hostname,omitempty"`
|
||||||
|
Hypervisor string `json:"hypervisor,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsDynamicallyScalable bool `json:"isdynamicallyscalable,omitempty"`
|
||||||
|
IsExtractable bool `json:"isextractable,omitempty"`
|
||||||
|
IsFeatured bool `json:"isfeatured,omitempty"`
|
||||||
|
IsPublic bool `json:"ispublic,omitempty"`
|
||||||
|
IsReady bool `json:"isready,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
OsTypeID string `json:"ostypeid,omitempty"`
|
||||||
|
OsTypeName string `json:"ostypename,omitempty"`
|
||||||
|
PasswordEnabled bool `json:"passwordenabled,omitempty"`
|
||||||
|
Project string `json:"project,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
Removed string `json:"removed,omitempty"`
|
||||||
|
Size int64 `json:"size,omitempty"`
|
||||||
|
SourceTemplateID string `json:"sourcetemplateid,omitempty"`
|
||||||
|
SSHKeyEnabled bool `json:"sshkeyenabled,omitempty"`
|
||||||
|
Status string `json:"status,omitempty"`
|
||||||
|
Zoneid string `json:"zoneid,omitempty"`
|
||||||
|
Zonename string `json:"zonename,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceType returns the type of the resource
|
||||||
|
func (*Template) ResourceType() string {
|
||||||
|
return "Template"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTemplates represents a template query filter
|
||||||
|
type ListTemplates struct {
|
||||||
|
TemplateFilter string `json:"templatefilter"` // featured, etc.
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Hypervisor string `json:"hypervisor,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
ShowRemoved bool `json:"showremoved,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListTemplates) name() string {
|
||||||
|
return "listTemplates"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListTemplates) response() interface{} {
|
||||||
|
return new(ListTemplatesResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTemplatesResponse represents a list of templates
|
||||||
|
type ListTemplatesResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
Template []Template `json:"template"`
|
||||||
|
}
|
176
vendor/github.com/exoscale/egoscale/topology.go
generated
vendored
176
vendor/github.com/exoscale/egoscale/topology.go
generated
vendored
|
@ -1,186 +1,163 @@
|
||||||
package egoscale
|
package egoscale
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetSecurityGroups returns all security groups
|
||||||
|
//
|
||||||
|
// Deprecated: do it yourself
|
||||||
func (exo *Client) GetSecurityGroups() (map[string]SecurityGroup, error) {
|
func (exo *Client) GetSecurityGroups() (map[string]SecurityGroup, error) {
|
||||||
var sgs map[string]SecurityGroup
|
var sgs map[string]SecurityGroup
|
||||||
params := url.Values{}
|
resp, err := exo.Request(&ListSecurityGroups{})
|
||||||
resp, err := exo.Request("listSecurityGroups", params)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var r ListSecurityGroupsResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sgs = make(map[string]SecurityGroup)
|
sgs = make(map[string]SecurityGroup)
|
||||||
for _, sg := range r.SecurityGroups {
|
for _, sg := range resp.(*ListSecurityGroupsResponse).SecurityGroup {
|
||||||
sgs[sg.Name] = *sg
|
sgs[sg.Name] = sg
|
||||||
}
|
}
|
||||||
return sgs, nil
|
return sgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (exo *Client) GetSecurityGroupId(name string) (string, error) {
|
// GetSecurityGroupID returns security group by name
|
||||||
params := url.Values{}
|
//
|
||||||
resp, err := exo.Request("listSecurityGroups", params)
|
// Deprecated: do it yourself
|
||||||
|
func (exo *Client) GetSecurityGroupID(name string) (string, error) {
|
||||||
|
resp, err := exo.Request(&ListSecurityGroups{SecurityGroupName: name})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
var r ListSecurityGroupsResponse
|
for _, sg := range resp.(*ListSecurityGroupsResponse).SecurityGroup {
|
||||||
err = json.Unmarshal(resp, &r)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, sg := range r.SecurityGroups {
|
|
||||||
if sg.Name == name {
|
if sg.Name == name {
|
||||||
return sg.Id, nil
|
return sg.ID, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (exo *Client) GetZones() (map[string]string, error) {
|
// GetAllZones returns all the zone id by name
|
||||||
|
//
|
||||||
|
// Deprecated: do it yourself
|
||||||
|
func (exo *Client) GetAllZones() (map[string]string, error) {
|
||||||
var zones map[string]string
|
var zones map[string]string
|
||||||
params := url.Values{}
|
resp, err := exo.Request(&ListZones{})
|
||||||
resp, err := exo.Request("listZones", params)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return zones, err
|
||||||
}
|
|
||||||
|
|
||||||
var r ListZonesResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zones = make(map[string]string)
|
zones = make(map[string]string)
|
||||||
for _, zone := range r.Zones {
|
for _, zone := range resp.(*ListZonesResponse).Zone {
|
||||||
zones[zone.Name] = zone.Id
|
zones[strings.ToLower(zone.Name)] = zone.ID
|
||||||
}
|
}
|
||||||
return zones, nil
|
return zones, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetProfiles returns a mapping of the service offerings by name
|
||||||
|
//
|
||||||
|
// Deprecated: do it yourself
|
||||||
func (exo *Client) GetProfiles() (map[string]string, error) {
|
func (exo *Client) GetProfiles() (map[string]string, error) {
|
||||||
|
profiles := make(map[string]string)
|
||||||
var profiles map[string]string
|
resp, err := exo.Request(&ListServiceOfferings{})
|
||||||
params := url.Values{}
|
|
||||||
resp, err := exo.Request("listServiceOfferings", params)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return profiles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var r ListServiceOfferingsResponse
|
for _, offering := range resp.(*ListServiceOfferingsResponse).ServiceOffering {
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
profiles[strings.ToLower(offering.Name)] = offering.ID
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
profiles = make(map[string]string)
|
|
||||||
for _, offering := range r.ServiceOfferings {
|
|
||||||
profiles[strings.ToLower(offering.Name)] = offering.Id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return profiles, nil
|
return profiles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetKeypairs returns the list of SSH keyPairs
|
||||||
|
//
|
||||||
|
// Deprecated: do it yourself
|
||||||
func (exo *Client) GetKeypairs() ([]SSHKeyPair, error) {
|
func (exo *Client) GetKeypairs() ([]SSHKeyPair, error) {
|
||||||
params := url.Values{}
|
var keypairs []SSHKeyPair
|
||||||
|
|
||||||
resp, err := exo.Request("listSSHKeyPairs", params)
|
|
||||||
|
|
||||||
|
resp, err := exo.Request(&ListSSHKeyPairs{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return keypairs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var r ListSSHKeyPairsResponse
|
r := resp.(*ListSSHKeyPairsResponse)
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
keypairs = make([]SSHKeyPair, r.Count)
|
||||||
return nil, err
|
for i, keypair := range r.SSHKeyPair {
|
||||||
}
|
keypairs[i] = keypair
|
||||||
|
|
||||||
var keypairs = make([]SSHKeyPair, r.Count, r.Count)
|
|
||||||
for i, keypair := range r.SSHKeyPairs {
|
|
||||||
keypairs[i] = *keypair
|
|
||||||
}
|
}
|
||||||
return keypairs, nil
|
return keypairs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAffinityGroups returns a mapping of the (anti-)affinity groups
|
||||||
|
//
|
||||||
|
// Deprecated: do it yourself
|
||||||
func (exo *Client) GetAffinityGroups() (map[string]string, error) {
|
func (exo *Client) GetAffinityGroups() (map[string]string, error) {
|
||||||
var affinitygroups map[string]string
|
var affinitygroups map[string]string
|
||||||
params := url.Values{}
|
|
||||||
|
|
||||||
resp, err := exo.Request("listAffinityGroups", params)
|
|
||||||
|
|
||||||
|
resp, err := exo.Request(&ListAffinityGroups{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return affinitygroups, err
|
||||||
}
|
|
||||||
|
|
||||||
var r ListAffinityGroupsResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
affinitygroups = make(map[string]string)
|
affinitygroups = make(map[string]string)
|
||||||
for _, affinitygroup := range r.AffinityGroups {
|
for _, affinitygroup := range resp.(*ListAffinityGroupsResponse).AffinityGroup {
|
||||||
affinitygroups[affinitygroup.Name] = affinitygroup.Id
|
affinitygroups[affinitygroup.Name] = affinitygroup.ID
|
||||||
}
|
}
|
||||||
return affinitygroups, nil
|
return affinitygroups, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (exo *Client) GetImages() (map[string]map[int]string, error) {
|
// GetImages list the available featured images and group them by name, then size.
|
||||||
var images map[string]map[int]string
|
//
|
||||||
images = make(map[string]map[int]string)
|
// Deprecated: do it yourself
|
||||||
|
func (exo *Client) GetImages() (map[string]map[int64]string, error) {
|
||||||
params := url.Values{}
|
var images map[string]map[int64]string
|
||||||
params.Set("templatefilter", "featured")
|
images = make(map[string]map[int64]string)
|
||||||
|
re := regexp.MustCompile(`^Linux (?P<name>.+?) (?P<version>[0-9.]+)\b`)
|
||||||
resp, err := exo.Request("listTemplates", params)
|
|
||||||
|
|
||||||
|
resp, err := exo.Request(&ListTemplates{
|
||||||
|
TemplateFilter: "featured",
|
||||||
|
ZoneID: "1", // XXX: Hack to list only CH-GVA
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return images, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var r ListTemplatesResponse
|
for _, template := range resp.(*ListTemplatesResponse).Template {
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
size := int64(template.Size >> 30) // B to GiB
|
||||||
return nil, err
|
|
||||||
}
|
fullname := strings.ToLower(template.Name)
|
||||||
|
|
||||||
|
if _, present := images[fullname]; !present {
|
||||||
|
images[fullname] = make(map[int64]string)
|
||||||
|
}
|
||||||
|
images[fullname][size] = template.ID
|
||||||
|
|
||||||
re := regexp.MustCompile(`^Linux (?P<name>.+?) (?P<version>[0-9.]+).*$`)
|
|
||||||
for _, template := range r.Templates {
|
|
||||||
size := int(template.Size / (1024 * 1024 * 1024))
|
|
||||||
submatch := re.FindStringSubmatch(template.Name)
|
submatch := re.FindStringSubmatch(template.Name)
|
||||||
if len(submatch) > 0 {
|
if len(submatch) > 0 {
|
||||||
name := strings.Replace(strings.ToLower(submatch[1]), " ", "-", -1)
|
name := strings.Replace(strings.ToLower(submatch[1]), " ", "-", -1)
|
||||||
version := submatch[2]
|
version := submatch[2]
|
||||||
image := fmt.Sprintf("%s-%s", name, version)
|
image := fmt.Sprintf("%s-%s", name, version)
|
||||||
|
|
||||||
_, present := images[image]
|
if _, present := images[image]; !present {
|
||||||
if !present {
|
images[image] = make(map[int64]string)
|
||||||
images[image] = make(map[int]string)
|
|
||||||
}
|
}
|
||||||
images[image][size] = template.Id
|
images[image][size] = template.ID
|
||||||
|
|
||||||
images[fmt.Sprintf("%s-%s", name, version)][size] = template.Id
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return images, nil
|
return images, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTopology returns an big, yet incomplete view of the world
|
||||||
|
//
|
||||||
|
// Deprecated: will go away in the future
|
||||||
func (exo *Client) GetTopology() (*Topology, error) {
|
func (exo *Client) GetTopology() (*Topology, error) {
|
||||||
|
zones, err := exo.GetAllZones()
|
||||||
zones, err := exo.GetZones()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -194,7 +171,7 @@ func (exo *Client) GetTopology() (*Topology, error) {
|
||||||
}
|
}
|
||||||
groups := make(map[string]string)
|
groups := make(map[string]string)
|
||||||
for k, v := range securityGroups {
|
for k, v := range securityGroups {
|
||||||
groups[k] = v.Id
|
groups[k] = v.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
keypairs, err := exo.GetKeypairs()
|
keypairs, err := exo.GetKeypairs()
|
||||||
|
@ -212,6 +189,7 @@ func (exo *Client) GetTopology() (*Topology, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
profiles, err := exo.GetProfiles()
|
profiles, err := exo.GetProfiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -219,9 +197,9 @@ func (exo *Client) GetTopology() (*Topology, error) {
|
||||||
|
|
||||||
topo := &Topology{
|
topo := &Topology{
|
||||||
Zones: zones,
|
Zones: zones,
|
||||||
Profiles: profiles,
|
|
||||||
Images: images,
|
Images: images,
|
||||||
Keypairs: keynames,
|
Keypairs: keynames,
|
||||||
|
Profiles: profiles,
|
||||||
AffinityGroups: affinitygroups,
|
AffinityGroups: affinitygroups,
|
||||||
SecurityGroups: groups,
|
SecurityGroups: groups,
|
||||||
}
|
}
|
||||||
|
|
513
vendor/github.com/exoscale/egoscale/types.go
generated
vendored
513
vendor/github.com/exoscale/egoscale/types.go
generated
vendored
|
@ -1,10 +1,10 @@
|
||||||
package egoscale
|
package egoscale
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Client represents the CloudStack API client
|
||||||
type Client struct {
|
type Client struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
endpoint string
|
endpoint string
|
||||||
|
@ -12,519 +12,12 @@ type Client struct {
|
||||||
apiSecret string
|
apiSecret string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Error struct {
|
// Topology represents a view of the servers
|
||||||
ErrorCode int `json:"errorcode"`
|
|
||||||
CSErrorCode int `json:"cserrorcode"`
|
|
||||||
ErrorText string `json:"errortext"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StandardResponse struct {
|
|
||||||
Success string `json:"success"`
|
|
||||||
DisplayText string `json:"displaytext"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Topology struct {
|
type Topology struct {
|
||||||
Zones map[string]string
|
Zones map[string]string
|
||||||
Images map[string]map[int]string
|
Images map[string]map[int64]string
|
||||||
Profiles map[string]string
|
Profiles map[string]string
|
||||||
Keypairs []string
|
Keypairs []string
|
||||||
SecurityGroups map[string]string
|
SecurityGroups map[string]string
|
||||||
AffinityGroups map[string]string
|
AffinityGroups map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type SecurityGroupRule struct {
|
|
||||||
Cidr string
|
|
||||||
IcmpType int
|
|
||||||
IcmpCode int
|
|
||||||
Port int
|
|
||||||
Protocol string
|
|
||||||
SecurityGroupId string
|
|
||||||
UserSecurityGroupList []UserSecurityGroup `json:"usersecuritygrouplist,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserSecurityGroup struct {
|
|
||||||
Group string `json:"group,omitempty"`
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type MachineProfile struct {
|
|
||||||
Name string
|
|
||||||
SecurityGroups []string
|
|
||||||
Keypair string
|
|
||||||
Userdata string
|
|
||||||
ServiceOffering string
|
|
||||||
Template string
|
|
||||||
Zone string
|
|
||||||
AffinityGroups []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListZonesResponse struct {
|
|
||||||
Count int `json:"count"`
|
|
||||||
Zones []*Zone `json:"zone"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Zone struct {
|
|
||||||
Allocationstate string `json:"allocationstate,omitempty"`
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
Displaytext string `json:"displaytext,omitempty"`
|
|
||||||
Domain string `json:"domain,omitempty"`
|
|
||||||
Domainid string `json:"domainid,omitempty"`
|
|
||||||
Domainname string `json:"domainname,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Internaldns1 string `json:"internaldns1,omitempty"`
|
|
||||||
Internaldns2 string `json:"internaldns2,omitempty"`
|
|
||||||
Ip6dns1 string `json:"ip6dns1,omitempty"`
|
|
||||||
Ip6dns2 string `json:"ip6dns2,omitempty"`
|
|
||||||
Localstorageenabled bool `json:"localstorageenabled,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Networktype string `json:"networktype,omitempty"`
|
|
||||||
Resourcedetails map[string]string `json:"resourcedetails,omitempty"`
|
|
||||||
Securitygroupsenabled bool `json:"securitygroupsenabled,omitempty"`
|
|
||||||
Vlan string `json:"vlan,omitempty"`
|
|
||||||
Zonetoken string `json:"zonetoken,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListServiceOfferingsResponse struct {
|
|
||||||
Count int `json:"count"`
|
|
||||||
ServiceOfferings []*ServiceOffering `json:"serviceoffering"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceOffering struct {
|
|
||||||
Cpunumber int `json:"cpunumber,omitempty"`
|
|
||||||
Cpuspeed int `json:"cpuspeed,omitempty"`
|
|
||||||
Displaytext string `json:"displaytext,omitempty"`
|
|
||||||
Domain string `json:"domain,omitempty"`
|
|
||||||
Domainid string `json:"domainid,omitempty"`
|
|
||||||
Hosttags string `json:"hosttags,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Iscustomized bool `json:"iscustomized,omitempty"`
|
|
||||||
Issystem bool `json:"issystem,omitempty"`
|
|
||||||
Isvolatile bool `json:"isvolatile,omitempty"`
|
|
||||||
Memory int `json:"memory,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Networkrate int `json:"networkrate,omitempty"`
|
|
||||||
Serviceofferingdetails map[string]string `json:"serviceofferingdetails,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListTemplatesResponse struct {
|
|
||||||
Count int `json:"count"`
|
|
||||||
Templates []*Template `json:"template"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Template struct {
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
Accountid string `json:"accountid,omitempty"`
|
|
||||||
Bootable bool `json:"bootable,omitempty"`
|
|
||||||
Checksum string `json:"checksum,omitempty"`
|
|
||||||
Created string `json:"created,omitempty"`
|
|
||||||
CrossZones bool `json:"crossZones,omitempty"`
|
|
||||||
Details map[string]string `json:"details,omitempty"`
|
|
||||||
Displaytext string `json:"displaytext,omitempty"`
|
|
||||||
Domain string `json:"domain,omitempty"`
|
|
||||||
Domainid string `json:"domainid,omitempty"`
|
|
||||||
Format string `json:"format,omitempty"`
|
|
||||||
Hostid string `json:"hostid,omitempty"`
|
|
||||||
Hostname string `json:"hostname,omitempty"`
|
|
||||||
Hypervisor string `json:"hypervisor,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Isdynamicallyscalable bool `json:"isdynamicallyscalable,omitempty"`
|
|
||||||
Isextractable bool `json:"isextractable,omitempty"`
|
|
||||||
Isfeatured bool `json:"isfeatured,omitempty"`
|
|
||||||
Ispublic bool `json:"ispublic,omitempty"`
|
|
||||||
Isready bool `json:"isready,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Ostypeid string `json:"ostypeid,omitempty"`
|
|
||||||
Ostypename string `json:"ostypename,omitempty"`
|
|
||||||
Passwordenabled bool `json:"passwordenabled,omitempty"`
|
|
||||||
Project string `json:"project,omitempty"`
|
|
||||||
Projectid string `json:"projectid,omitempty"`
|
|
||||||
Removed string `json:"removed,omitempty"`
|
|
||||||
Size int64 `json:"size,omitempty"`
|
|
||||||
Sourcetemplateid string `json:"sourcetemplateid,omitempty"`
|
|
||||||
Sshkeyenabled bool `json:"sshkeyenabled,omitempty"`
|
|
||||||
Status string `json:"status,omitempty"`
|
|
||||||
Zoneid string `json:"zoneid,omitempty"`
|
|
||||||
Zonename string `json:"zonename,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListSSHKeyPairsResponse struct {
|
|
||||||
Count int `json:"count"`
|
|
||||||
SSHKeyPairs []*SSHKeyPair `json:"sshkeypair"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SSHKeyPair struct {
|
|
||||||
Fingerprint string `json:"fingerprint,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListAffinityGroupsResponse struct {
|
|
||||||
Count int `json:"count"`
|
|
||||||
AffinityGroups []*AffinityGroup `json:"affinitygroup"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AffinityGroup struct {
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Type string `json:"type,omitempty"`
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Domainid string `json:"domainid,omitempty"`
|
|
||||||
Domain string `json:"domain,omitempty"`
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateAffinityGroupResponseWrapper struct {
|
|
||||||
Wrapped AffinityGroup `json:"affinitygroup"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListSecurityGroupsResponse struct {
|
|
||||||
Count int `json:"count"`
|
|
||||||
SecurityGroups []*SecurityGroup `json:"securitygroup"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SecurityGroup struct {
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
Domain string `json:"domain,omitempty"`
|
|
||||||
Domainid string `json:"domainid,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Project string `json:"project,omitempty"`
|
|
||||||
Projectid string `json:"projectid,omitempty"`
|
|
||||||
IngressRules []struct {
|
|
||||||
RuleId string `json:"ruleid,omitempty"`
|
|
||||||
Protocol string `json:"protocol,omitempty"`
|
|
||||||
StartPort int `json:"startport,omitempty"`
|
|
||||||
EndPort int `json:"endport,omitempty"`
|
|
||||||
Cidr string `json:"cidr,omitempty"`
|
|
||||||
IcmpCode int `json:"icmpcode,omitempty"`
|
|
||||||
IcmpType int `json:"icmptype,omitempty"`
|
|
||||||
Tags []string `json:"tags,omitempty"`
|
|
||||||
} `json:"ingressrule,omitempty"`
|
|
||||||
EgressRules []struct {
|
|
||||||
RuleId string `json:"ruleid,omitempty"`
|
|
||||||
Protocol string `json:"protocol,omitempty"`
|
|
||||||
StartPort int `json:"startport,omitempty"`
|
|
||||||
EndPort int `json:"endport,omitempty"`
|
|
||||||
Cidr string `json:"cidr,omitempty"`
|
|
||||||
IcmpCode int `json:"icmpcode,omitempty"`
|
|
||||||
IcmpType int `json:"icmptype,omitempty"`
|
|
||||||
Tags []string `json:"tags,omitempty"`
|
|
||||||
} `json:"egressrule,omitempty"`
|
|
||||||
Tags []string `json:"tags,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateSecurityGroupResponseWrapper struct {
|
|
||||||
Wrapped CreateSecurityGroupResponse `json:"securitygroup"`
|
|
||||||
}
|
|
||||||
type CreateSecurityGroupResponse struct {
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
Domain string `json:"domain,omitempty"`
|
|
||||||
Domainid string `json:"domainid,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Project string `json:"project,omitempty"`
|
|
||||||
Projectid string `json:"projectid,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthorizeSecurityGroupIngressResponse struct {
|
|
||||||
JobID string `json:"jobid,omitempty"`
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
Cidr string `json:"cidr,omitempty"`
|
|
||||||
Endport int `json:"endport,omitempty"`
|
|
||||||
Icmpcode int `json:"icmpcode,omitempty"`
|
|
||||||
Icmptype int `json:"icmptype,omitempty"`
|
|
||||||
Protocol string `json:"protocol,omitempty"`
|
|
||||||
Ruleid string `json:"ruleid,omitempty"`
|
|
||||||
Securitygroupname string `json:"securitygroupname,omitempty"`
|
|
||||||
Startport int `json:"startport,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthorizeSecurityGroupEgressResponse struct {
|
|
||||||
JobID string `json:"jobid,omitempty"`
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
Cidr string `json:"cidr,omitempty"`
|
|
||||||
Endport int `json:"endport,omitempty"`
|
|
||||||
Icmpcode int `json:"icmpcode,omitempty"`
|
|
||||||
Icmptype int `json:"icmptype,omitempty"`
|
|
||||||
Protocol string `json:"protocol,omitempty"`
|
|
||||||
Ruleid string `json:"ruleid,omitempty"`
|
|
||||||
Securitygroupname string `json:"securitygroupname,omitempty"`
|
|
||||||
Startport int `json:"startport,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeployVirtualMachineWrappedResponse struct {
|
|
||||||
Wrapped DeployVirtualMachineResponse `json:"virtualmachine"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeployVirtualMachineResponse struct {
|
|
||||||
JobID string `json:"jobid,omitempty"`
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
Affinitygroup []struct {
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
Domain string `json:"domain,omitempty"`
|
|
||||||
Domainid string `json:"domainid,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Type string `json:"type,omitempty"`
|
|
||||||
VirtualmachineIds []string `json:"virtualmachineIds,omitempty"`
|
|
||||||
} `json:"affinitygroup,omitempty"`
|
|
||||||
Cpunumber int `json:"cpunumber,omitempty"`
|
|
||||||
Cpuspeed int `json:"cpuspeed,omitempty"`
|
|
||||||
Cpuused string `json:"cpuused,omitempty"`
|
|
||||||
Created string `json:"created,omitempty"`
|
|
||||||
Details map[string]string `json:"details,omitempty"`
|
|
||||||
Diskioread int64 `json:"diskioread,omitempty"`
|
|
||||||
Diskiowrite int64 `json:"diskiowrite,omitempty"`
|
|
||||||
Diskkbsread int64 `json:"diskkbsread,omitempty"`
|
|
||||||
Diskkbswrite int64 `json:"diskkbswrite,omitempty"`
|
|
||||||
Displayname string `json:"displayname,omitempty"`
|
|
||||||
Displayvm bool `json:"displayvm,omitempty"`
|
|
||||||
Domain string `json:"domain,omitempty"`
|
|
||||||
Domainid string `json:"domainid,omitempty"`
|
|
||||||
Forvirtualnetwork bool `json:"forvirtualnetwork,omitempty"`
|
|
||||||
Group string `json:"group,omitempty"`
|
|
||||||
Groupid string `json:"groupid,omitempty"`
|
|
||||||
Guestosid string `json:"guestosid,omitempty"`
|
|
||||||
Haenable bool `json:"haenable,omitempty"`
|
|
||||||
Hostid string `json:"hostid,omitempty"`
|
|
||||||
Hostname string `json:"hostname,omitempty"`
|
|
||||||
Hypervisor string `json:"hypervisor,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Instancename string `json:"instancename,omitempty"`
|
|
||||||
Isdynamicallyscalable bool `json:"isdynamicallyscalable,omitempty"`
|
|
||||||
Isodisplaytext string `json:"isodisplaytext,omitempty"`
|
|
||||||
Isoid string `json:"isoid,omitempty"`
|
|
||||||
Isoname string `json:"isoname,omitempty"`
|
|
||||||
Keypair string `json:"keypair,omitempty"`
|
|
||||||
Memory int `json:"memory,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Networkkbsread int64 `json:"networkkbsread,omitempty"`
|
|
||||||
Networkkbswrite int64 `json:"networkkbswrite,omitempty"`
|
|
||||||
Nic []struct {
|
|
||||||
Broadcasturi string `json:"broadcasturi,omitempty"`
|
|
||||||
Gateway string `json:"gateway,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Ipaddress string `json:"ipaddress,omitempty"`
|
|
||||||
Isdefault bool `json:"isdefault,omitempty"`
|
|
||||||
Isolationuri string `json:"isolationuri,omitempty"`
|
|
||||||
Macaddress string `json:"macaddress,omitempty"`
|
|
||||||
Netmask string `json:"netmask,omitempty"`
|
|
||||||
Networkid string `json:"networkid,omitempty"`
|
|
||||||
Networkname string `json:"networkname,omitempty"`
|
|
||||||
Secondaryip []string `json:"secondaryip,omitempty"`
|
|
||||||
Traffictype string `json:"traffictype,omitempty"`
|
|
||||||
Type string `json:"type,omitempty"`
|
|
||||||
} `json:"nic,omitempty"`
|
|
||||||
Password string `json:"password,omitempty"`
|
|
||||||
Passwordenabled bool `json:"passwordenabled,omitempty"`
|
|
||||||
Project string `json:"project,omitempty"`
|
|
||||||
Projectid string `json:"projectid,omitempty"`
|
|
||||||
Publicip string `json:"publicip,omitempty"`
|
|
||||||
Publicipid string `json:"publicipid,omitempty"`
|
|
||||||
Rootdeviceid int64 `json:"rootdeviceid,omitempty"`
|
|
||||||
Rootdevicetype string `json:"rootdevicetype,omitempty"`
|
|
||||||
Serviceofferingid string `json:"serviceofferingid,omitempty"`
|
|
||||||
Serviceofferingname string `json:"serviceofferingname,omitempty"`
|
|
||||||
Servicestate string `json:"servicestate,omitempty"`
|
|
||||||
State string `json:"state,omitempty"`
|
|
||||||
Templatedisplaytext string `json:"templatedisplaytext,omitempty"`
|
|
||||||
Templateid string `json:"templateid,omitempty"`
|
|
||||||
Templatename string `json:"templatename,omitempty"`
|
|
||||||
Zoneid string `json:"zoneid,omitempty"`
|
|
||||||
Zonename string `json:"zonename,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type QueryAsyncJobResultResponse struct {
|
|
||||||
Accountid string `json:"accountid,omitempty"`
|
|
||||||
Cmd string `json:"cmd,omitempty"`
|
|
||||||
Created string `json:"created,omitempty"`
|
|
||||||
Jobinstanceid string `json:"jobinstanceid,omitempty"`
|
|
||||||
Jobinstancetype string `json:"jobinstancetype,omitempty"`
|
|
||||||
Jobprocstatus int `json:"jobprocstatus,omitempty"`
|
|
||||||
Jobresult json.RawMessage `json:"jobresult,omitempty"`
|
|
||||||
Jobresultcode int `json:"jobresultcode,omitempty"`
|
|
||||||
Jobresulttype string `json:"jobresulttype,omitempty"`
|
|
||||||
Jobstatus int `json:"jobstatus,omitempty"`
|
|
||||||
Userid string `json:"userid,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListVirtualMachinesResponse struct {
|
|
||||||
Count int `json:"count"`
|
|
||||||
VirtualMachines []*VirtualMachine `json:"virtualmachine"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type VirtualMachine struct {
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
Cpunumber int `json:"cpunumber,omitempty"`
|
|
||||||
Cpuspeed int `json:"cpuspeed,omitempty"`
|
|
||||||
Cpuused string `json:"cpuused,omitempty"`
|
|
||||||
Created string `json:"created,omitempty"`
|
|
||||||
Details map[string]string `json:"details,omitempty"`
|
|
||||||
Diskioread int64 `json:"diskioread,omitempty"`
|
|
||||||
Diskiowrite int64 `json:"diskiowrite,omitempty"`
|
|
||||||
Diskkbsread int64 `json:"diskkbsread,omitempty"`
|
|
||||||
Diskkbswrite int64 `json:"diskkbswrite,omitempty"`
|
|
||||||
Displayname string `json:"displayname,omitempty"`
|
|
||||||
Displayvm bool `json:"displayvm,omitempty"`
|
|
||||||
Domain string `json:"domain,omitempty"`
|
|
||||||
Domainid string `json:"domainid,omitempty"`
|
|
||||||
Forvirtualnetwork bool `json:"forvirtualnetwork,omitempty"`
|
|
||||||
Group string `json:"group,omitempty"`
|
|
||||||
Groupid string `json:"groupid,omitempty"`
|
|
||||||
Guestosid string `json:"guestosid,omitempty"`
|
|
||||||
Haenable bool `json:"haenable,omitempty"`
|
|
||||||
Hostid string `json:"hostid,omitempty"`
|
|
||||||
Hostname string `json:"hostname,omitempty"`
|
|
||||||
Hypervisor string `json:"hypervisor,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Instancename string `json:"instancename,omitempty"`
|
|
||||||
Isdynamicallyscalable bool `json:"isdynamicallyscalable,omitempty"`
|
|
||||||
Isodisplaytext string `json:"isodisplaytext,omitempty"`
|
|
||||||
Isoid string `json:"isoid,omitempty"`
|
|
||||||
Isoname string `json:"isoname,omitempty"`
|
|
||||||
Keypair string `json:"keypair,omitempty"`
|
|
||||||
Memory int `json:"memory,omitempty"`
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Networkkbsread int64 `json:"networkkbsread,omitempty"`
|
|
||||||
Networkkbswrite int64 `json:"networkkbswrite,omitempty"`
|
|
||||||
Nic []struct {
|
|
||||||
Broadcasturi string `json:"broadcasturi,omitempty"`
|
|
||||||
Gateway string `json:"gateway,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Ip6address string `json:"ip6address,omitempty"`
|
|
||||||
Ip6cidr string `json:"ip6cidr,omitempty"`
|
|
||||||
Ip6gateway string `json:"ip6gateway,omitempty"`
|
|
||||||
Ipaddress string `json:"ipaddress,omitempty"`
|
|
||||||
Isdefault bool `json:"isdefault,omitempty"`
|
|
||||||
Isolationuri string `json:"isolationuri,omitempty"`
|
|
||||||
Macaddress string `json:"macaddress,omitempty"`
|
|
||||||
Netmask string `json:"netmask,omitempty"`
|
|
||||||
Networkid string `json:"networkid,omitempty"`
|
|
||||||
Networkname string `json:"networkname,omitempty"`
|
|
||||||
Secondaryip []struct {
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
IpAddress string `json:"ipaddress,omitempty"`
|
|
||||||
} `json:"secondaryip,omitempty"`
|
|
||||||
Traffictype string `json:"traffictype,omitempty"`
|
|
||||||
Type string `json:"type,omitempty"`
|
|
||||||
} `json:"nic,omitempty"`
|
|
||||||
Password string `json:"password,omitempty"`
|
|
||||||
Passwordenabled bool `json:"passwordenabled,omitempty"`
|
|
||||||
Project string `json:"project,omitempty"`
|
|
||||||
Projectid string `json:"projectid,omitempty"`
|
|
||||||
Publicip string `json:"publicip,omitempty"`
|
|
||||||
Publicipid string `json:"publicipid,omitempty"`
|
|
||||||
Rootdeviceid int64 `json:"rootdeviceid,omitempty"`
|
|
||||||
Rootdevicetype string `json:"rootdevicetype,omitempty"`
|
|
||||||
SecurityGroups []struct {
|
|
||||||
Account string `json:"account,omitempty"`
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
Id string `json:"id,omitempty"`
|
|
||||||
Name string `json:"name,omitemtpy"`
|
|
||||||
Tags []string `json:"tags,omitempty"`
|
|
||||||
} `json:"securitygroup,omitempty"`
|
|
||||||
Serviceofferingid string `json:"serviceofferingid,omitempty"`
|
|
||||||
Serviceofferingname string `json:"serviceofferingname,omitempty"`
|
|
||||||
Servicestate string `json:"servicestate,omitempty"`
|
|
||||||
State string `json:"state,omitempty"`
|
|
||||||
Templatedisplaytext string `json:"templatedisplaytext,omitempty"`
|
|
||||||
Templateid string `json:"templateid,omitempty"`
|
|
||||||
Templatename string `json:"templatename,omitempty"`
|
|
||||||
Zoneid string `json:"zoneid,omitempty"`
|
|
||||||
Zonename string `json:"zonename,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StartVirtualMachineResponse struct {
|
|
||||||
JobID string `json:"jobid,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StopVirtualMachineResponse struct {
|
|
||||||
JobID string `json:"jobid,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DestroyVirtualMachineResponse struct {
|
|
||||||
JobID string `json:"jobid,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RebootVirtualMachineResponse struct {
|
|
||||||
JobID string `json:"jobid,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateSSHKeyPairWrappedResponse struct {
|
|
||||||
Wrapped CreateSSHKeyPairResponse `json:"keypair,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateSSHKeyPairResponse struct {
|
|
||||||
Privatekey string `json:"privatekey,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RemoveIpFromNicResponse struct {
|
|
||||||
JobID string `json:"jobid,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AddIpToNicResponse struct {
|
|
||||||
Id string `json:"id"`
|
|
||||||
IpAddress string `json:"ipaddress"`
|
|
||||||
NetworkId string `json:"networkid"`
|
|
||||||
NicId string `json:"nicid"`
|
|
||||||
VmId string `json:"virtualmachineid"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateAffinityGroupResponse struct {
|
|
||||||
JobId string `json:"jobid,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteAffinityGroupResponse struct {
|
|
||||||
JobId string `json:"jobid,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteSSHKeyPairResponse struct {
|
|
||||||
Privatekey string `json:"privatekey,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DNSDomain struct {
|
|
||||||
Id int64 `json:"id"`
|
|
||||||
UserId int64 `json:"user_id"`
|
|
||||||
RegistrantId int64 `json:"registrant_id,omitempty"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
UnicodeName string `json:"unicode_name"`
|
|
||||||
Token string `json:"token"`
|
|
||||||
State string `json:"state"`
|
|
||||||
Language string `json:"language,omitempty"`
|
|
||||||
Lockable bool `json:"lockable"`
|
|
||||||
AutoRenew bool `json:"auto_renew"`
|
|
||||||
WhoisProtected bool `json:"whois_protected"`
|
|
||||||
RecordCount int64 `json:"record_count"`
|
|
||||||
ServiceCount int64 `json:"service_count"`
|
|
||||||
ExpiresOn string `json:"expires_on,omitempty"`
|
|
||||||
CreatedAt string `json:"created_at"`
|
|
||||||
UpdatedAt string `json:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DNSDomainCreateRequest struct {
|
|
||||||
Domain struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
} `json:"domain"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DNSRecord struct {
|
|
||||||
Id int64 `json:"id,omitempty"`
|
|
||||||
DomainId int64 `json:"domain_id,omitempty"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Ttl int `json:"ttl,omitempty"`
|
|
||||||
CreatedAt string `json:"created_at,omitempty"`
|
|
||||||
UpdatedAt string `json:"updated_at,omitempty"`
|
|
||||||
Content string `json:"content"`
|
|
||||||
RecordType string `json:"record_type"`
|
|
||||||
Prio int `json:"prio,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DNSRecordResponse struct {
|
|
||||||
Record DNSRecord `json:"record"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DNSError struct {
|
|
||||||
Name []string `json:"name"`
|
|
||||||
}
|
|
||||||
|
|
43
vendor/github.com/exoscale/egoscale/users.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/users.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// User represents a User
|
||||||
|
type User struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
AccountID string `json:"accountid,omitempty"`
|
||||||
|
AccountType string `json:"accounttype,omitempty"`
|
||||||
|
APIKey string `json:"apikey,omitempty"`
|
||||||
|
Created string `json:"created,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
FirstName string `json:"firstname,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsCallerChildDomain bool `json:"iscallerchilddomain,omitempty"`
|
||||||
|
IsDefault bool `json:"isdefault,omitempty"`
|
||||||
|
LastName string `json:"lastname,omitempty"`
|
||||||
|
SecretKey string `json:"secretkey,omitempty"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
UserName string `json:"username,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterUserKeys registers a new set of key of the given user
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/registerUserKeys.html
|
||||||
|
type RegisterUserKeys struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RegisterUserKeys) name() string {
|
||||||
|
return "registerUserKeys"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RegisterUserKeys) response() interface{} {
|
||||||
|
return new(RegisterUserKeysResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterUserKeysResponse represents a new set of UserKeys
|
||||||
|
//
|
||||||
|
// NB: only the APIKey and SecretKey will be filled
|
||||||
|
type RegisterUserKeysResponse struct {
|
||||||
|
UserKeys User `json:"userkeys"`
|
||||||
|
}
|
514
vendor/github.com/exoscale/egoscale/virtual_machines.go
generated
vendored
Normal file
514
vendor/github.com/exoscale/egoscale/virtual_machines.go
generated
vendored
Normal file
|
@ -0,0 +1,514 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
import "net"
|
||||||
|
|
||||||
|
// VirtualMachine reprents a virtual machine
|
||||||
|
type VirtualMachine struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
ClusterID string `json:"clusterid,omitempty"`
|
||||||
|
ClusterName string `json:"clustername,omitempty"`
|
||||||
|
CPUNumber int64 `json:"cpunumber,omitempty"`
|
||||||
|
CPUSpeed int64 `json:"cpuspeed,omitempty"`
|
||||||
|
CPUUsed string `json:"cpuused,omitempty"`
|
||||||
|
Created string `json:"created,omitempty"`
|
||||||
|
Details map[string]string `json:"details,omitempty"`
|
||||||
|
DiskIoRead int64 `json:"diskioread,omitempty"`
|
||||||
|
DiskIoWrite int64 `json:"diskiowrite,omitempty"`
|
||||||
|
DiskKbsRead int64 `json:"diskkbsread,omitempty"`
|
||||||
|
DiskKbsWrite int64 `json:"diskkbswrite,omitempty"`
|
||||||
|
DiskOfferingID string `json:"diskofferingid,omitempty"`
|
||||||
|
DiskOfferingName string `json:"diskofferingname,omitempty"`
|
||||||
|
DisplayName string `json:"displayname,omitempty"`
|
||||||
|
DisplayVM bool `json:"displayvm,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ForVirtualNetwork bool `json:"forvirtualnetwork,omitempty"`
|
||||||
|
Group string `json:"group,omitempty"`
|
||||||
|
GroupID string `json:"groupid,omitempty"`
|
||||||
|
GuestOsID string `json:"guestosid,omitempty"`
|
||||||
|
HaEnable bool `json:"haenable,omitempty"`
|
||||||
|
HostID string `json:"hostid,omitempty"`
|
||||||
|
HostName string `json:"hostname,omitempty"`
|
||||||
|
Hypervisor string `json:"hypervisor,omitempty"`
|
||||||
|
InstanceName string `json:"instancename,omitempty"` // root only
|
||||||
|
IsDynamicallyScalable bool `json:"isdynamicallyscalable,omitempty"`
|
||||||
|
IsoDisplayText string `json:"isodisplaytext,omitempty"`
|
||||||
|
IsoID string `json:"isoid,omitempty"`
|
||||||
|
IsoName string `json:"isoname,omitempty"`
|
||||||
|
KeyPair string `json:"keypair,omitempty"`
|
||||||
|
Memory int64 `json:"memory,omitempty"`
|
||||||
|
MemoryIntFreeKbs int64 `json:"memoryintfreekbs,omitempty"`
|
||||||
|
MemoryKbs int64 `json:"memorykbs,omitempty"`
|
||||||
|
MemoryTargetKbs int64 `json:"memorytargetkbs,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkKbsRead int64 `json:"networkkbsread,omitempty"`
|
||||||
|
NetworkKbsWrite int64 `json:"networkkbswrite,omitempty"`
|
||||||
|
OsCategoryID string `json:"oscategoryid,omitempty"`
|
||||||
|
OsTypeID int64 `json:"ostypeid,omitempty"`
|
||||||
|
Password string `json:"password,omitempty"`
|
||||||
|
PasswordEnabled bool `json:"passwordenabled,omitempty"`
|
||||||
|
PCIDevices string `json:"pcidevices,omitempty"` // not in the doc
|
||||||
|
PodID string `json:"podid,omitempty"`
|
||||||
|
PodName string `json:"podname,omitempty"`
|
||||||
|
Project string `json:"project,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
PublicIP string `json:"publicip,omitempty"`
|
||||||
|
PublicIPID string `json:"publicipid,omitempty"`
|
||||||
|
RootDeviceID int64 `json:"rootdeviceid,omitempty"`
|
||||||
|
RootDeviceType string `json:"rootdevicetype,omitempty"`
|
||||||
|
ServiceOfferingID string `json:"serviceofferingid,omitempty"`
|
||||||
|
ServiceOfferingName string `json:"serviceofferingname,omitempty"`
|
||||||
|
ServiceState string `json:"servicestate,omitempty"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
TemplateDisplayText string `json:"templatedisplaytext,omitempty"`
|
||||||
|
TemplateID string `json:"templateid,omitempty"`
|
||||||
|
TemplateName string `json:"templatename,omitempty"`
|
||||||
|
UserID string `json:"userid,omitempty"` // not in the doc
|
||||||
|
UserName string `json:"username,omitempty"` // not in the doc
|
||||||
|
Vgpu string `json:"vgpu,omitempty"` // not in the doc
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
ZoneName string `json:"zonename,omitempty"`
|
||||||
|
AffinityGroup []AffinityGroup `json:"affinitygroup,omitempty"`
|
||||||
|
Nic []Nic `json:"nic,omitempty"`
|
||||||
|
SecurityGroup []SecurityGroup `json:"securitygroup,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
JobID string `json:"jobid,omitempty"`
|
||||||
|
JobStatus JobStatusType `json:"jobstatus,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceType returns the type of the resource
|
||||||
|
func (*VirtualMachine) ResourceType() string {
|
||||||
|
return "UserVM"
|
||||||
|
}
|
||||||
|
|
||||||
|
// NicsByType returns the corresponding interfaces base on the given type
|
||||||
|
func (vm *VirtualMachine) NicsByType(nicType string) []Nic {
|
||||||
|
nics := make([]Nic, 0)
|
||||||
|
for _, nic := range vm.Nic {
|
||||||
|
if nic.Type == nicType {
|
||||||
|
// XXX The CloudStack API forgets to specify it
|
||||||
|
nic.VirtualMachineID = vm.ID
|
||||||
|
nics = append(nics, nic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nics
|
||||||
|
}
|
||||||
|
|
||||||
|
// NicByNetworkID returns the corresponding interface based on the given NetworkID
|
||||||
|
func (vm *VirtualMachine) NicByNetworkID(networkID string) *Nic {
|
||||||
|
for _, nic := range vm.Nic {
|
||||||
|
if nic.NetworkID == networkID {
|
||||||
|
nic.VirtualMachineID = vm.ID
|
||||||
|
return &nic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NicByID returns the corresponding interface base on its ID
|
||||||
|
func (vm *VirtualMachine) NicByID(nicID string) *Nic {
|
||||||
|
for _, nic := range vm.Nic {
|
||||||
|
if nic.ID == nicID {
|
||||||
|
nic.VirtualMachineID = vm.ID
|
||||||
|
return &nic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPToNetwork represents a mapping between ip and networks
|
||||||
|
type IPToNetwork struct {
|
||||||
|
IP string `json:"ip,omitempty"`
|
||||||
|
IPV6 string `json:"ipv6,omitempty"`
|
||||||
|
NetworkID string `json:"networkid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// VirtualMachineResponse represents a generic Virtual Machine response
|
||||||
|
type VirtualMachineResponse struct {
|
||||||
|
VirtualMachine VirtualMachine `json:"virtualmachine"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeployVirtualMachine (Async) represents the machine creation
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/deployVirtualMachine.html
|
||||||
|
type DeployVirtualMachine struct {
|
||||||
|
ServiceOfferingID string `json:"serviceofferingid"`
|
||||||
|
TemplateID string `json:"templateid"`
|
||||||
|
ZoneID string `json:"zoneid"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
AffinityGroupIDs []string `json:"affinitygroupids,omitempty"`
|
||||||
|
AffinityGroupNames []string `json:"affinitygroupnames,omitempty"`
|
||||||
|
CustomID string `json:"customid,omitempty"` // root only
|
||||||
|
DeploymentPlanner string `json:"deploymentplanner,omitempty"` // root only
|
||||||
|
Details map[string]string `json:"details,omitempty"`
|
||||||
|
DiskOfferingID string `json:"diskofferingid,omitempty"`
|
||||||
|
DisplayName string `json:"displayname,omitempty"`
|
||||||
|
DisplayVM bool `json:"displayvm,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Group string `json:"group,omitempty"`
|
||||||
|
HostID string `json:"hostid,omitempty"`
|
||||||
|
Hypervisor string `json:"hypervisor,omitempty"`
|
||||||
|
IP6Address net.IP `json:"ip6address,omitempty"`
|
||||||
|
IPAddress net.IP `json:"ipaddress,omitempty"`
|
||||||
|
IPToNetworkList []IPToNetwork `json:"iptonetworklist,omitempty"`
|
||||||
|
Keyboard string `json:"keyboard,omitempty"`
|
||||||
|
KeyPair string `json:"keypair,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkIDs []string `json:"networkids,omitempty"` // mutually exclusive with IPToNetworkList
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
RootDiskSize int64 `json:"rootdisksize,omitempty"` // in GiB
|
||||||
|
SecurityGroupIDs []string `json:"securitygroupids,omitempty"`
|
||||||
|
SecurityGroupNames []string `json:"securitygroupnames,omitempty"` // does nothing, mutually exclusive
|
||||||
|
Size string `json:"size,omitempty"` // mutually exclusive with DiskOfferingID
|
||||||
|
StartVM bool `json:"startvm,omitempty"`
|
||||||
|
UserData string `json:"userdata,omitempty"` // the client is responsible to base64/gzip it
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeployVirtualMachine) name() string {
|
||||||
|
return "deployVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeployVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(DeployVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeployVirtualMachineResponse represents a deployed VM instance
|
||||||
|
type DeployVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// StartVirtualMachine (Async) represents the creation of the virtual machine
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/startVirtualMachine.html
|
||||||
|
type StartVirtualMachine struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
DeploymentPlanner string `json:"deploymentplanner,omitempty"` // root only
|
||||||
|
HostID string `json:"hostid,omitempty"` // root only
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*StartVirtualMachine) name() string {
|
||||||
|
return "startVirtualMachine"
|
||||||
|
}
|
||||||
|
func (*StartVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(StartVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartVirtualMachineResponse represents a started VM instance
|
||||||
|
type StartVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// StopVirtualMachine (Async) represents the stopping of the virtual machine
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/stopVirtualMachine.html
|
||||||
|
type StopVirtualMachine struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Forced bool `json:"forced,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*StopVirtualMachine) name() string {
|
||||||
|
return "stopVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*StopVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(StopVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopVirtualMachineResponse represents a stopped VM instance
|
||||||
|
type StopVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// RebootVirtualMachine (Async) represents the rebooting of the virtual machine
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/rebootVirtualMachine.html
|
||||||
|
type RebootVirtualMachine struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RebootVirtualMachine) name() string {
|
||||||
|
return "rebootVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RebootVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(RebootVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RebootVirtualMachineResponse represents a rebooted VM instance
|
||||||
|
type RebootVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// RestoreVirtualMachine (Async) represents the restoration of the virtual machine
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/restoreVirtualMachine.html
|
||||||
|
type RestoreVirtualMachine struct {
|
||||||
|
VirtualMachineID string `json:"virtualmachineid"`
|
||||||
|
TemplateID string `json:"templateid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RestoreVirtualMachine) name() string {
|
||||||
|
return "restoreVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RestoreVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(RestoreVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestoreVirtualMachineResponse represents a restored VM instance
|
||||||
|
type RestoreVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// RecoverVirtualMachine represents the restoration of the virtual machine
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/recoverVirtualMachine.html
|
||||||
|
type RecoverVirtualMachine struct {
|
||||||
|
ID string `json:"virtualmachineid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RecoverVirtualMachine) name() string {
|
||||||
|
return "recoverVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RecoverVirtualMachine) response() interface{} {
|
||||||
|
return new(RecoverVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecoverVirtualMachineResponse represents a recovered VM instance
|
||||||
|
type RecoverVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// DestroyVirtualMachine (Async) represents the destruction of the virtual machine
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/destroyVirtualMachine.html
|
||||||
|
type DestroyVirtualMachine struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Expunge bool `json:"expunge,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DestroyVirtualMachine) name() string {
|
||||||
|
return "destroyVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DestroyVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(DestroyVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DestroyVirtualMachineResponse represents a destroyed VM instance
|
||||||
|
type DestroyVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// UpdateVirtualMachine represents the update of the virtual machine
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/updateVirtualMachine.html
|
||||||
|
type UpdateVirtualMachine struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
CustomID string `json:"customid,omitempty"` // root only
|
||||||
|
Details map[string]string `json:"details,omitempty"`
|
||||||
|
DisplayName string `json:"displayname,omitempty"`
|
||||||
|
DisplayVM bool `json:"displayvm,omitempty"`
|
||||||
|
Group string `json:"group,omitempty"`
|
||||||
|
HAEnable bool `json:"haenable,omitempty"`
|
||||||
|
IsDynamicallyScalable bool `json:"isdynamicallyscalable,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"` // must reboot
|
||||||
|
OsTypeID int64 `json:"ostypeid,omitempty"`
|
||||||
|
SecurityGroupIDs []string `json:"securitygroupids,omitempty"`
|
||||||
|
UserData string `json:"userdata,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateVirtualMachine) name() string {
|
||||||
|
return "updateVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateVirtualMachine) response() interface{} {
|
||||||
|
return new(UpdateVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateVirtualMachineResponse represents an updated VM instance
|
||||||
|
type UpdateVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// ExpungeVirtualMachine represents the annihilation of a VM
|
||||||
|
type ExpungeVirtualMachine struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ExpungeVirtualMachine) name() string {
|
||||||
|
return "expungeVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ExpungeVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScaleVirtualMachine (Async) represents the scaling of a VM
|
||||||
|
//
|
||||||
|
// ChangeServiceForVirtualMachine does the same thing but returns the
|
||||||
|
// new Virtual Machine which is more consistent with the rest of the API.
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/scaleVirtualMachine.html
|
||||||
|
type ScaleVirtualMachine struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
ServiceOfferingID string `json:"serviceofferingid"`
|
||||||
|
Details map[string]string `json:"details,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ScaleVirtualMachine) name() string {
|
||||||
|
return "scaleVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ScaleVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(booleanAsyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangeServiceForVirtualMachine represents the scaling of a VM
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/changeServiceForVirtualMachine.html
|
||||||
|
type ChangeServiceForVirtualMachine ScaleVirtualMachine
|
||||||
|
|
||||||
|
func (*ChangeServiceForVirtualMachine) name() string {
|
||||||
|
return "changeServiceForVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ChangeServiceForVirtualMachine) response() interface{} {
|
||||||
|
return new(ChangeServiceForVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangeServiceForVirtualMachineResponse represents an changed VM instance
|
||||||
|
type ChangeServiceForVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// ResetPasswordForVirtualMachine (Async) represents the scaling of a VM
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/resetPasswordForVirtualMachine.html
|
||||||
|
type ResetPasswordForVirtualMachine ScaleVirtualMachine
|
||||||
|
|
||||||
|
func (*ResetPasswordForVirtualMachine) name() string {
|
||||||
|
return "resetPasswordForVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ResetPasswordForVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(ResetPasswordForVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetPasswordForVirtualMachineResponse represents the updated vm
|
||||||
|
type ResetPasswordForVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// GetVMPassword asks for an encrypted password
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/getVMPassword.html
|
||||||
|
type GetVMPassword struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*GetVMPassword) name() string {
|
||||||
|
return "getVMPassword"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*GetVMPassword) response() interface{} {
|
||||||
|
return new(GetVMPasswordResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVMPasswordResponse represents the encrypted password
|
||||||
|
type GetVMPasswordResponse struct {
|
||||||
|
// Base64 encrypted password for the VM
|
||||||
|
EncryptedPassword string `json:"encryptedpassword"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListVirtualMachines represents a search for a VM
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listVirtualMachine.html
|
||||||
|
type ListVirtualMachines struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
AffinityGroupID string `json:"affinitygroupid,omitempty"`
|
||||||
|
Details map[string]string `json:"details,omitempty"`
|
||||||
|
DisplayVM bool `json:"displayvm,omitempty"` // root only
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ForVirtualNetwork bool `json:"forvirtualnetwork,omitempty"`
|
||||||
|
GroupID string `json:"groupid,omitempty"`
|
||||||
|
HostID string `json:"hostid,omitempty"`
|
||||||
|
Hypervisor string `json:"hypervisor,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IDs []string `json:"ids,omitempty"` // mutually exclusive with id
|
||||||
|
IsoID string `json:"isoid,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
KeyPair string `json:"keypair,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkID string `json:"networkid,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
PodID string `json:"podid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
ServiceOfferindID string `json:"serviceofferingid,omitempty"`
|
||||||
|
State string `json:"state,omitempty"` // Running, Stopped, Present, ...
|
||||||
|
StorageID string `json:"storageid,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
TemplateID string `json:"templateid,omitempty"`
|
||||||
|
UserID string `json:"userid,omitempty"`
|
||||||
|
VpcID string `json:"vpcid,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListVirtualMachines) name() string {
|
||||||
|
return "listVirtualMachines"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListVirtualMachines) response() interface{} {
|
||||||
|
return new(ListVirtualMachinesResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListVirtualMachinesResponse represents a list of virtual machines
|
||||||
|
type ListVirtualMachinesResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
VirtualMachine []VirtualMachine `json:"virtualmachine"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNicToVirtualMachine (Async) adds a NIC to a VM
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/addNicToVirtualMachine.html
|
||||||
|
type AddNicToVirtualMachine struct {
|
||||||
|
NetworkID string `json:"networkid"`
|
||||||
|
VirtualMachineID string `json:"virtualmachineid"`
|
||||||
|
IPAddress net.IP `json:"ipaddress,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*AddNicToVirtualMachine) name() string {
|
||||||
|
return "addNicToVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*AddNicToVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(AddNicToVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNicToVirtualMachineResponse represents the modified VM
|
||||||
|
type AddNicToVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// RemoveNicFromVirtualMachine (Async) removes a NIC from a VM
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/removeNicFromVirtualMachine.html
|
||||||
|
type RemoveNicFromVirtualMachine struct {
|
||||||
|
NicID string `json:"nicid"`
|
||||||
|
VirtualMachineID string `json:"virtualmachineid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RemoveNicFromVirtualMachine) name() string {
|
||||||
|
return "removeNicFromVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RemoveNicFromVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(RemoveNicFromVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveNicFromVirtualMachineResponse represents the modified VM
|
||||||
|
type RemoveNicFromVirtualMachineResponse VirtualMachineResponse
|
||||||
|
|
||||||
|
// UpdateDefaultNicForVirtualMachine (Async) adds a NIC to a VM
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/updateDefaultNicForVirtualMachine.html
|
||||||
|
type UpdateDefaultNicForVirtualMachine struct {
|
||||||
|
NetworkID string `json:"networkid"`
|
||||||
|
VirtualMachineID string `json:"virtualmachineid"`
|
||||||
|
IPAddress net.IP `json:"ipaddress,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateDefaultNicForVirtualMachine) name() string {
|
||||||
|
return "updateDefaultNicForVirtualMachine"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateDefaultNicForVirtualMachine) asyncResponse() interface{} {
|
||||||
|
return new(UpdateDefaultNicForVirtualMachineResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateDefaultNicForVirtualMachineResponse represents the modified VM
|
||||||
|
type UpdateDefaultNicForVirtualMachineResponse VirtualMachineResponse
|
159
vendor/github.com/exoscale/egoscale/vm.go
generated
vendored
159
vendor/github.com/exoscale/egoscale/vm.go
generated
vendored
|
@ -1,159 +0,0 @@
|
||||||
package egoscale
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (exo *Client) CreateVirtualMachine(p MachineProfile) (string, error) {
|
|
||||||
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("serviceofferingid", p.ServiceOffering)
|
|
||||||
params.Set("templateid", p.Template)
|
|
||||||
params.Set("zoneid", p.Zone)
|
|
||||||
|
|
||||||
params.Set("displayname", p.Name)
|
|
||||||
if len(p.Userdata) > 0 {
|
|
||||||
params.Set("userdata", base64.StdEncoding.EncodeToString([]byte(p.Userdata)))
|
|
||||||
}
|
|
||||||
if len(p.Keypair) > 0 {
|
|
||||||
params.Set("keypair", p.Keypair)
|
|
||||||
}
|
|
||||||
if len(p.AffinityGroups) > 0 {
|
|
||||||
params.Set("affinitygroupnames", strings.Join(p.AffinityGroups, ","))
|
|
||||||
}
|
|
||||||
|
|
||||||
params.Set("securitygroupids", strings.Join(p.SecurityGroups, ","))
|
|
||||||
|
|
||||||
resp, err := exo.Request("deployVirtualMachine", params)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r DeployVirtualMachineResponse
|
|
||||||
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.JobID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) StartVirtualMachine(id string) (string, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("id", id)
|
|
||||||
|
|
||||||
resp, err := exo.Request("startVirtualMachine", params)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r StartVirtualMachineResponse
|
|
||||||
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.JobID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) StopVirtualMachine(id string) (string, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("id", id)
|
|
||||||
|
|
||||||
resp, err := exo.Request("stopVirtualMachine", params)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r StopVirtualMachineResponse
|
|
||||||
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.JobID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) RebootVirtualMachine(id string) (string, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("id", id)
|
|
||||||
|
|
||||||
resp, err := exo.Request("rebootVirtualMachine", params)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r RebootVirtualMachineResponse
|
|
||||||
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.JobID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) DestroyVirtualMachine(id string) (string, error) {
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("id", id)
|
|
||||||
|
|
||||||
resp, err := exo.Request("destroyVirtualMachine", params)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r DestroyVirtualMachineResponse
|
|
||||||
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.JobID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) GetVirtualMachine(id string) (*VirtualMachine, error) {
|
|
||||||
|
|
||||||
params := url.Values{}
|
|
||||||
params.Set("id", id)
|
|
||||||
|
|
||||||
resp, err := exo.Request("listVirtualMachines", params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r ListVirtualMachinesResponse
|
|
||||||
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(r.VirtualMachines) == 1 {
|
|
||||||
machine := r.VirtualMachines[0]
|
|
||||||
return machine, nil
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("cannot retrieve virtualmachine with id %s", id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (exo *Client) ListVirtualMachines() ([]*VirtualMachine, error) {
|
|
||||||
|
|
||||||
resp, err := exo.Request("listVirtualMachines", url.Values{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var r ListVirtualMachinesResponse
|
|
||||||
if err := json.Unmarshal(resp, &r); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.VirtualMachines, nil
|
|
||||||
}
|
|
106
vendor/github.com/exoscale/egoscale/vm_groups.go
generated
vendored
Normal file
106
vendor/github.com/exoscale/egoscale/vm_groups.go
generated
vendored
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
// InstanceGroup represents a group of VM
|
||||||
|
type InstanceGroup struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
Created string `json:"created,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Project string `json:"project,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstanceGroupResponse represents a VM group
|
||||||
|
type InstanceGroupResponse struct {
|
||||||
|
InstanceGroup InstanceGroup `json:"instancegroup"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateInstanceGroup creates a VM group
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/createInstanceGroup.html
|
||||||
|
type CreateInstanceGroup struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateInstanceGroup) name() string {
|
||||||
|
return "createInstanceGroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CreateInstanceGroup) response() interface{} {
|
||||||
|
return new(CreateInstanceGroupResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateInstanceGroupResponse represents a freshly created VM group
|
||||||
|
type CreateInstanceGroupResponse InstanceGroupResponse
|
||||||
|
|
||||||
|
// UpdateInstanceGroup creates a VM group
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/updateInstanceGroup.html
|
||||||
|
type UpdateInstanceGroup struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateInstanceGroup) name() string {
|
||||||
|
return "updateInstanceGroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UpdateInstanceGroup) response() interface{} {
|
||||||
|
return new(UpdateInstanceGroupResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateInstanceGroupResponse represents an updated VM group
|
||||||
|
type UpdateInstanceGroupResponse InstanceGroupResponse
|
||||||
|
|
||||||
|
// DeleteInstanceGroup creates a VM group
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/deleteInstanceGroup.html
|
||||||
|
type DeleteInstanceGroup struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteInstanceGroup) name() string {
|
||||||
|
return "deleteInstanceGroup"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeleteInstanceGroup) response() interface{} {
|
||||||
|
return new(booleanSyncResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListInstanceGroups lists VM groups
|
||||||
|
//
|
||||||
|
// CloudStack API: http://cloudstack.apache.org/api/apidocs-4.10/apis/listInstanceGroups.html
|
||||||
|
type ListInstanceGroups struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListInstanceGroups) name() string {
|
||||||
|
return "listInstanceGroups"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListInstanceGroups) response() interface{} {
|
||||||
|
return new(ListInstanceGroupsResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListInstanceGroupsResponse represents a list of instance groups
|
||||||
|
type ListInstanceGroupsResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
InstanceGroup []InstanceGroup `json:"instancegroup"`
|
||||||
|
}
|
121
vendor/github.com/exoscale/egoscale/volumes.go
generated
vendored
Normal file
121
vendor/github.com/exoscale/egoscale/volumes.go
generated
vendored
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Volume represents a volume linked to a VM
|
||||||
|
type Volume struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
Attached string `json:"attached,omitempty"`
|
||||||
|
ChainInfo string `json:"chaininfo,omitempty"`
|
||||||
|
Created string `json:"created,omitempty"`
|
||||||
|
Destroyed bool `json:"destroyed,omitempty"`
|
||||||
|
DisplayVolume bool `json:"displayvolume,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
QuiesceVM bool `json:"quiescevm,omitempty"`
|
||||||
|
ServiceOfferingDisplayText string `json:"serviceofferingdisplaytext,omitempty"`
|
||||||
|
ServiceOfferingID string `json:"serviceofferingid,omitempty"`
|
||||||
|
ServiceOfferingName string `json:"serviceofferingname,omitempty"`
|
||||||
|
Size uint64 `json:"size,omitempty"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
VirtualMachineID string `json:"virtualmachineid,omitempty"`
|
||||||
|
VMName string `json:"vmname,omitempty"`
|
||||||
|
VMState string `json:"vmstate,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
ZoneName string `json:"zonename,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
JobID string `json:"jobid,omitempty"`
|
||||||
|
JobStatus JobStatusType `json:"jobstatus,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceType returns the type of the resource
|
||||||
|
func (*Volume) ResourceType() string {
|
||||||
|
return "Volume"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResizeVolume (Async) resizes a volume
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/resizeVolume.html
|
||||||
|
type ResizeVolume struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
DiskOfferingID string `json:"diskofferingid,omitempty"`
|
||||||
|
ShrinkOk bool `json:"shrinkok,omitempty"`
|
||||||
|
Size int64 `json:"size,omitempty"` // in GiB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ResizeVolume) name() string {
|
||||||
|
return "resizeVolume"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ResizeVolume) asyncResponse() interface{} {
|
||||||
|
return new(ResizeVolumeResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResizeVolumeResponse represents the new Volume
|
||||||
|
type ResizeVolumeResponse struct {
|
||||||
|
Volume Volume `json:"volume"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListVolumes represents a query listing volumes
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listVolumes.html
|
||||||
|
type ListVolumes struct {
|
||||||
|
Account string `json:"account,omitempty"`
|
||||||
|
DiskOfferingID string `json:"diskoffering,omitempty"`
|
||||||
|
DisplayVolume string `json:"displayvolume,omitempty"` // root only
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
HostID string `json:"hostid,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
IsRecursive bool `json:"isrecursive,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
ListAll bool `json:"listall,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
PodID string `json:"podid,omitempty"`
|
||||||
|
ProjectID string `json:"projectid,omitempty"`
|
||||||
|
StorageID string `json:"storageid,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
VirtualMachineID string `json:"virtualmachineid,omitempty"`
|
||||||
|
ZoneID string `json:"zoneid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListVolumes) name() string {
|
||||||
|
return "listVolumes"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListVolumes) response() interface{} {
|
||||||
|
return new(ListVolumesResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListVolumesResponse represents a list of volumes
|
||||||
|
type ListVolumesResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
Volume []Volume `json:"volume"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRootVolumeForVirtualMachine returns the root volume of a VM
|
||||||
|
//
|
||||||
|
// Deprecated: helper function shouldn't be used
|
||||||
|
func (exo *Client) GetRootVolumeForVirtualMachine(virtualMachineID string) (*Volume, error) {
|
||||||
|
resp, err := exo.Request(&ListVolumes{
|
||||||
|
VirtualMachineID: virtualMachineID,
|
||||||
|
Type: "ROOT",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := resp.(*ListVolumesResponse)
|
||||||
|
if r.Count != 1 {
|
||||||
|
return nil, fmt.Errorf("Expected exactly one volume for %v, got %d", virtualMachineID, r.Count)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &(r.Volume[0]), nil
|
||||||
|
}
|
60
vendor/github.com/exoscale/egoscale/zones.go
generated
vendored
Normal file
60
vendor/github.com/exoscale/egoscale/zones.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package egoscale
|
||||||
|
|
||||||
|
import "net"
|
||||||
|
|
||||||
|
// Zone represents a data center
|
||||||
|
type Zone struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
AllocationState string `json:"allocationstate,omitempty"`
|
||||||
|
Capacity string `json:"capacity,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
DhcpProvider string `json:"dhcpprovider,omitempty"`
|
||||||
|
DisplayText string `json:"displaytext,omitempty"`
|
||||||
|
DNS1 net.IP `json:"dns1,omitempty"`
|
||||||
|
DNS2 net.IP `json:"dns2,omitempty"`
|
||||||
|
Domain string `json:"domain,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
DomainName string `json:"domainname,omitempty"`
|
||||||
|
GuestCidrAddress string `json:"guestcidraddress,omitempty"`
|
||||||
|
InternalDNS1 net.IP `json:"internaldns1,omitempty"`
|
||||||
|
InternalDNS2 net.IP `json:"internaldns2,omitempty"`
|
||||||
|
IP6DNS1 net.IP `json:"ip6dns1,omitempty"`
|
||||||
|
IP6DNS2 net.IP `json:"ip6dns2,omitempty"`
|
||||||
|
LocalStorageEnabled bool `json:"localstorageenabled,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NetworkType string `json:"networktype,omitempty"`
|
||||||
|
ResourceDetails map[string]string `json:"resourcedetails,omitempty"`
|
||||||
|
SecurityGroupsEnabled bool `json:"securitygroupsenabled,omitempty"`
|
||||||
|
Vlan string `json:"vlan,omitempty"`
|
||||||
|
ZoneToken string `json:"zonetoken,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListZones represents a query for zones
|
||||||
|
//
|
||||||
|
// CloudStack API: https://cloudstack.apache.org/api/apidocs-4.10/apis/listZones.html
|
||||||
|
type ListZones struct {
|
||||||
|
Available bool `json:"available,omitempty"`
|
||||||
|
DomainID string `json:"domainid,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Keyword string `json:"keyword,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Page int `json:"page,omitempty"`
|
||||||
|
PageSize int `json:"pagesize,omitempty"`
|
||||||
|
ShowCapacities bool `json:"showcapacities,omitempty"`
|
||||||
|
Tags []ResourceTag `json:"tags,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListZones) name() string {
|
||||||
|
return "listZones"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ListZones) response() interface{} {
|
||||||
|
return new(ListZonesResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListZonesResponse represents a list of zones
|
||||||
|
type ListZonesResponse struct {
|
||||||
|
Count int `json:"count"`
|
||||||
|
Zone []Zone `json:"zone"`
|
||||||
|
}
|
1
vendor/github.com/xenolf/lego/acme/http.go
generated
vendored
1
vendor/github.com/xenolf/lego/acme/http.go
generated
vendored
|
@ -18,6 +18,7 @@ var UserAgent string
|
||||||
// HTTPClient is an HTTP client with a reasonable timeout value.
|
// HTTPClient is an HTTP client with a reasonable timeout value.
|
||||||
var HTTPClient = http.Client{
|
var HTTPClient = http.Client{
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
Dial: (&net.Dialer{
|
Dial: (&net.Dialer{
|
||||||
Timeout: 30 * time.Second,
|
Timeout: 30 * time.Second,
|
||||||
KeepAlive: 30 * time.Second,
|
KeepAlive: 30 * time.Second,
|
||||||
|
|
214
vendor/github.com/xenolf/lego/providers/dns/cloudxns/cloudxns.go
generated
vendored
Normal file
214
vendor/github.com/xenolf/lego/providers/dns/cloudxns/cloudxns.go
generated
vendored
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
// Package cloudxns implements a DNS provider for solving the DNS-01 challenge
|
||||||
|
// using cloudxns DNS.
|
||||||
|
package cloudxns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/xenolf/lego/acme"
|
||||||
|
)
|
||||||
|
|
||||||
|
const cloudXNSBaseURL = "https://www.cloudxns.net/api2/"
|
||||||
|
|
||||||
|
// DNSProvider is an implementation of the acme.ChallengeProvider interface
|
||||||
|
type DNSProvider struct {
|
||||||
|
apiKey string
|
||||||
|
secretKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProvider returns a DNSProvider instance configured for cloudxns.
|
||||||
|
// Credentials must be passed in the environment variables: CLOUDXNS_API_KEY
|
||||||
|
// and CLOUDXNS_SECRET_KEY.
|
||||||
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
|
apiKey := os.Getenv("CLOUDXNS_API_KEY")
|
||||||
|
secretKey := os.Getenv("CLOUDXNS_SECRET_KEY")
|
||||||
|
return NewDNSProviderCredentials(apiKey, secretKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||||
|
// DNSProvider instance configured for cloudxns.
|
||||||
|
func NewDNSProviderCredentials(apiKey, secretKey string) (*DNSProvider, error) {
|
||||||
|
if apiKey == "" || secretKey == "" {
|
||||||
|
return nil, fmt.Errorf("CloudXNS credentials missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DNSProvider{
|
||||||
|
apiKey: apiKey,
|
||||||
|
secretKey: secretKey,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Present creates a TXT record to fulfil the dns-01 challenge.
|
||||||
|
func (c *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
|
fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
|
||||||
|
zoneID, err := c.getHostedZoneID(fqdn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.addTxtRecord(zoneID, fqdn, value, ttl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CleanUp removes the TXT record matching the specified parameters.
|
||||||
|
func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
|
fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
|
||||||
|
zoneID, err := c.getHostedZoneID(fqdn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
recordID, err := c.findTxtRecord(zoneID, fqdn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.delTxtRecord(recordID, zoneID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DNSProvider) getHostedZoneID(fqdn string) (string, error) {
|
||||||
|
type Data struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Domain string `json:"domain"`
|
||||||
|
}
|
||||||
|
|
||||||
|
authZone, err := acme.FindZoneByFqdn(fqdn, acme.RecursiveNameservers)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := c.makeRequest("GET", "domain", nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var domains []Data
|
||||||
|
err = json.Unmarshal(result, &domains)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, data := range domains {
|
||||||
|
if data.Domain == authZone {
|
||||||
|
return data.ID, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("Zone %s not found in cloudxns for domain %s", authZone, fqdn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DNSProvider) findTxtRecord(zoneID, fqdn string) (string, error) {
|
||||||
|
result, err := c.makeRequest("GET", fmt.Sprintf("record/%s?host_id=0&offset=0&row_num=2000", zoneID), nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var records []cloudXNSRecord
|
||||||
|
err = json.Unmarshal(result, &records)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, record := range records {
|
||||||
|
if record.Host == acme.UnFqdn(fqdn) && record.Type == "TXT" {
|
||||||
|
return record.RecordID, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("No existing record found for %s", fqdn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DNSProvider) addTxtRecord(zoneID, fqdn, value string, ttl int) error {
|
||||||
|
id, err := strconv.Atoi(zoneID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := cloudXNSRecord{
|
||||||
|
ID: id,
|
||||||
|
Host: acme.UnFqdn(fqdn),
|
||||||
|
Value: value,
|
||||||
|
Type: "TXT",
|
||||||
|
LineID: 1,
|
||||||
|
TTL: ttl,
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.makeRequest("POST", "record", body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DNSProvider) delTxtRecord(recordID, zoneID string) error {
|
||||||
|
_, err := c.makeRequest("DELETE", fmt.Sprintf("record/%s/%s", recordID, zoneID), nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DNSProvider) hmac(url, date, body string) string {
|
||||||
|
sum := md5.Sum([]byte(c.apiKey + url + body + date + c.secretKey))
|
||||||
|
return hex.EncodeToString(sum[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *DNSProvider) makeRequest(method, uri string, body []byte) (json.RawMessage, error) {
|
||||||
|
type APIResponse struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data json.RawMessage `json:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
url := cloudXNSBaseURL + uri
|
||||||
|
req, err := http.NewRequest(method, url, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
requestDate := time.Now().Format(time.RFC1123Z)
|
||||||
|
|
||||||
|
req.Header.Set("API-KEY", c.apiKey)
|
||||||
|
req.Header.Set("API-REQUEST-DATE", requestDate)
|
||||||
|
req.Header.Set("API-HMAC", c.hmac(url, requestDate, string(body)))
|
||||||
|
req.Header.Set("API-FORMAT", "json")
|
||||||
|
|
||||||
|
resp, err := acme.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var r APIResponse
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Code != 1 {
|
||||||
|
return nil, fmt.Errorf("CloudXNS API Error: %s", r.Message)
|
||||||
|
}
|
||||||
|
return r.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type cloudXNSRecord struct {
|
||||||
|
ID int `json:"domain_id,omitempty"`
|
||||||
|
RecordID string `json:"record_id,omitempty"`
|
||||||
|
|
||||||
|
Host string `json:"host"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
LineID int `json:"line_id,string"`
|
||||||
|
TTL int `json:"ttl,string"`
|
||||||
|
}
|
8
vendor/github.com/xenolf/lego/providers/dns/dns_providers.go
generated
vendored
8
vendor/github.com/xenolf/lego/providers/dns/dns_providers.go
generated
vendored
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/xenolf/lego/providers/dns/auroradns"
|
"github.com/xenolf/lego/providers/dns/auroradns"
|
||||||
"github.com/xenolf/lego/providers/dns/azure"
|
"github.com/xenolf/lego/providers/dns/azure"
|
||||||
"github.com/xenolf/lego/providers/dns/cloudflare"
|
"github.com/xenolf/lego/providers/dns/cloudflare"
|
||||||
|
"github.com/xenolf/lego/providers/dns/cloudxns"
|
||||||
"github.com/xenolf/lego/providers/dns/digitalocean"
|
"github.com/xenolf/lego/providers/dns/digitalocean"
|
||||||
"github.com/xenolf/lego/providers/dns/dnsimple"
|
"github.com/xenolf/lego/providers/dns/dnsimple"
|
||||||
"github.com/xenolf/lego/providers/dns/dnsmadeeasy"
|
"github.com/xenolf/lego/providers/dns/dnsmadeeasy"
|
||||||
|
@ -15,8 +16,9 @@ import (
|
||||||
"github.com/xenolf/lego/providers/dns/dyn"
|
"github.com/xenolf/lego/providers/dns/dyn"
|
||||||
"github.com/xenolf/lego/providers/dns/exoscale"
|
"github.com/xenolf/lego/providers/dns/exoscale"
|
||||||
"github.com/xenolf/lego/providers/dns/gandi"
|
"github.com/xenolf/lego/providers/dns/gandi"
|
||||||
"github.com/xenolf/lego/providers/dns/godaddy"
|
"github.com/xenolf/lego/providers/dns/gandiv5"
|
||||||
"github.com/xenolf/lego/providers/dns/googlecloud"
|
"github.com/xenolf/lego/providers/dns/googlecloud"
|
||||||
|
"github.com/xenolf/lego/providers/dns/godaddy"
|
||||||
"github.com/xenolf/lego/providers/dns/linode"
|
"github.com/xenolf/lego/providers/dns/linode"
|
||||||
"github.com/xenolf/lego/providers/dns/namecheap"
|
"github.com/xenolf/lego/providers/dns/namecheap"
|
||||||
"github.com/xenolf/lego/providers/dns/ns1"
|
"github.com/xenolf/lego/providers/dns/ns1"
|
||||||
|
@ -39,6 +41,8 @@ func NewDNSChallengeProviderByName(name string) (acme.ChallengeProvider, error)
|
||||||
provider, err = auroradns.NewDNSProvider()
|
provider, err = auroradns.NewDNSProvider()
|
||||||
case "cloudflare":
|
case "cloudflare":
|
||||||
provider, err = cloudflare.NewDNSProvider()
|
provider, err = cloudflare.NewDNSProvider()
|
||||||
|
case "cloudxns":
|
||||||
|
provider, err = cloudxns.NewDNSProvider()
|
||||||
case "digitalocean":
|
case "digitalocean":
|
||||||
provider, err = digitalocean.NewDNSProvider()
|
provider, err = digitalocean.NewDNSProvider()
|
||||||
case "dnsimple":
|
case "dnsimple":
|
||||||
|
@ -53,6 +57,8 @@ func NewDNSChallengeProviderByName(name string) (acme.ChallengeProvider, error)
|
||||||
provider, err = exoscale.NewDNSProvider()
|
provider, err = exoscale.NewDNSProvider()
|
||||||
case "gandi":
|
case "gandi":
|
||||||
provider, err = gandi.NewDNSProvider()
|
provider, err = gandi.NewDNSProvider()
|
||||||
|
case "gandiv5":
|
||||||
|
provider, err = gandiv5.NewDNSProvider()
|
||||||
case "gcloud":
|
case "gcloud":
|
||||||
provider, err = googlecloud.NewDNSProvider()
|
provider, err = googlecloud.NewDNSProvider()
|
||||||
case "godaddy":
|
case "godaddy":
|
||||||
|
|
26
vendor/github.com/xenolf/lego/providers/dns/exoscale/exoscale.go
generated
vendored
26
vendor/github.com/xenolf/lego/providers/dns/exoscale/exoscale.go
generated
vendored
|
@ -48,25 +48,25 @@ func (c *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
recordId, err := c.FindExistingRecordId(zone, recordName)
|
recordID, err := c.FindExistingRecordId(zone, recordName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
record := egoscale.DNSRecord{
|
record := egoscale.DNSRecord{
|
||||||
Name: recordName,
|
Name: recordName,
|
||||||
Ttl: ttl,
|
TTL: ttl,
|
||||||
Content: value,
|
Content: value,
|
||||||
RecordType: "TXT",
|
RecordType: "TXT",
|
||||||
}
|
}
|
||||||
|
|
||||||
if recordId == 0 {
|
if recordID == 0 {
|
||||||
_, err := c.client.CreateRecord(zone, record)
|
_, err := c.client.CreateRecord(zone, record)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("Error while creating DNS record: " + err.Error())
|
return errors.New("Error while creating DNS record: " + err.Error())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
record.Id = recordId
|
record.ID = recordID
|
||||||
_, err := c.client.UpdateRecord(zone, record)
|
_, err := c.client.UpdateRecord(zone, record)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("Error while updating DNS record: " + err.Error())
|
return errors.New("Error while updating DNS record: " + err.Error())
|
||||||
|
@ -84,17 +84,13 @@ func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
recordId, err := c.FindExistingRecordId(zone, recordName)
|
recordID, err := c.FindExistingRecordId(zone, recordName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if recordId != 0 {
|
if recordID != 0 {
|
||||||
record := egoscale.DNSRecord{
|
err = c.client.DeleteRecord(zone, recordID)
|
||||||
Id: recordId,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = c.client.DeleteRecord(zone, record)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("Error while deleting DNS record: " + err.Error())
|
return errors.New("Error while deleting DNS record: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -106,13 +102,13 @@ func (c *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
// Query Exoscale to find an existing record for this name.
|
// Query Exoscale to find an existing record for this name.
|
||||||
// Returns nil if no record could be found
|
// Returns nil if no record could be found
|
||||||
func (c *DNSProvider) FindExistingRecordId(zone, recordName string) (int64, error) {
|
func (c *DNSProvider) FindExistingRecordId(zone, recordName string) (int64, error) {
|
||||||
responses, err := c.client.GetRecords(zone)
|
records, err := c.client.GetRecords(zone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, errors.New("Error while retrievening DNS records: " + err.Error())
|
return -1, errors.New("Error while retrievening DNS records: " + err.Error())
|
||||||
}
|
}
|
||||||
for _, response := range responses {
|
for _, record := range records {
|
||||||
if response.Record.Name == recordName {
|
if record.Name == recordName {
|
||||||
return response.Record.Id, nil
|
return record.ID, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0, nil
|
return 0, nil
|
||||||
|
|
203
vendor/github.com/xenolf/lego/providers/dns/gandiv5/gandiv5.go
generated
vendored
Normal file
203
vendor/github.com/xenolf/lego/providers/dns/gandiv5/gandiv5.go
generated
vendored
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
// Package gandiv5 implements a DNS provider for solving the DNS-01
|
||||||
|
// challenge using Gandi LiveDNS api.
|
||||||
|
package gandiv5
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/xenolf/lego/acme"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Gandi API reference: http://doc.livedns.gandi.net/
|
||||||
|
|
||||||
|
var (
|
||||||
|
// endpoint is the Gandi API endpoint used by Present and
|
||||||
|
// CleanUp. It is overridden during tests.
|
||||||
|
endpoint = "https://dns.api.gandi.net/api/v5"
|
||||||
|
// findZoneByFqdn determines the DNS zone of an fqdn. It is overridden
|
||||||
|
// during tests.
|
||||||
|
findZoneByFqdn = acme.FindZoneByFqdn
|
||||||
|
)
|
||||||
|
|
||||||
|
// inProgressInfo contains information about an in-progress challenge
|
||||||
|
type inProgressInfo struct {
|
||||||
|
fieldName string
|
||||||
|
authZone string
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSProvider is an implementation of the
|
||||||
|
// acme.ChallengeProviderTimeout interface that uses Gandi's LiveDNS
|
||||||
|
// API to manage TXT records for a domain.
|
||||||
|
type DNSProvider struct {
|
||||||
|
apiKey string
|
||||||
|
inProgressFQDNs map[string]inProgressInfo
|
||||||
|
inProgressMu sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProvider returns a DNSProvider instance configured for Gandi.
|
||||||
|
// Credentials must be passed in the environment variable: GANDIV5_API_KEY.
|
||||||
|
func NewDNSProvider() (*DNSProvider, error) {
|
||||||
|
apiKey := os.Getenv("GANDIV5_API_KEY")
|
||||||
|
return NewDNSProviderCredentials(apiKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDNSProviderCredentials uses the supplied credentials to return a
|
||||||
|
// DNSProvider instance configured for Gandi.
|
||||||
|
func NewDNSProviderCredentials(apiKey string) (*DNSProvider, error) {
|
||||||
|
if apiKey == "" {
|
||||||
|
return nil, fmt.Errorf("Gandi DNS: No Gandi API Key given")
|
||||||
|
}
|
||||||
|
return &DNSProvider{
|
||||||
|
apiKey: apiKey,
|
||||||
|
inProgressFQDNs: make(map[string]inProgressInfo),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Present creates a TXT record using the specified parameters.
|
||||||
|
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
|
fqdn, value, ttl := acme.DNS01Record(domain, keyAuth)
|
||||||
|
if ttl < 300 {
|
||||||
|
ttl = 300 // 300 is gandi minimum value for ttl
|
||||||
|
}
|
||||||
|
// find authZone
|
||||||
|
authZone, err := findZoneByFqdn(fqdn, acme.RecursiveNameservers)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Gandi DNS: findZoneByFqdn failure: %v", err)
|
||||||
|
}
|
||||||
|
// determine name of TXT record
|
||||||
|
if !strings.HasSuffix(
|
||||||
|
strings.ToLower(fqdn), strings.ToLower("."+authZone)) {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"Gandi DNS: unexpected authZone %s for fqdn %s", authZone, fqdn)
|
||||||
|
}
|
||||||
|
name := fqdn[:len(fqdn)-len("."+authZone)]
|
||||||
|
// acquire lock and check there is not a challenge already in
|
||||||
|
// progress for this value of authZone
|
||||||
|
d.inProgressMu.Lock()
|
||||||
|
defer d.inProgressMu.Unlock()
|
||||||
|
// add TXT record into authZone
|
||||||
|
err = d.addTXTRecord(acme.UnFqdn(authZone), name, value, ttl)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// save data necessary for CleanUp
|
||||||
|
d.inProgressFQDNs[fqdn] = inProgressInfo{
|
||||||
|
authZone: authZone,
|
||||||
|
fieldName: name,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CleanUp removes the TXT record matching the specified parameters.
|
||||||
|
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
|
fqdn, _, _ := acme.DNS01Record(domain, keyAuth)
|
||||||
|
// acquire lock and retrieve authZone
|
||||||
|
d.inProgressMu.Lock()
|
||||||
|
defer d.inProgressMu.Unlock()
|
||||||
|
if _, ok := d.inProgressFQDNs[fqdn]; !ok {
|
||||||
|
// if there is no cleanup information then just return
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
fieldName := d.inProgressFQDNs[fqdn].fieldName
|
||||||
|
authZone := d.inProgressFQDNs[fqdn].authZone
|
||||||
|
delete(d.inProgressFQDNs, fqdn)
|
||||||
|
// delete TXT record from authZone
|
||||||
|
err := d.deleteTXTRecord(acme.UnFqdn(authZone), fieldName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timeout returns the values (20*time.Minute, 20*time.Second) which
|
||||||
|
// are used by the acme package as timeout and check interval values
|
||||||
|
// when checking for DNS record propagation with Gandi.
|
||||||
|
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
||||||
|
return 20 * time.Minute, 20 * time.Second
|
||||||
|
}
|
||||||
|
|
||||||
|
// types for JSON method calls and parameters
|
||||||
|
|
||||||
|
type addFieldRequest struct {
|
||||||
|
RRSetTTL int `json:"rrset_ttl"`
|
||||||
|
RRSetValues []string `json:"rrset_values"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type deleteFieldRequest struct {
|
||||||
|
Delete bool `json:"delete"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// types for JSON responses
|
||||||
|
|
||||||
|
type responseStruct struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// POSTing/Marshalling/Unmarshalling
|
||||||
|
|
||||||
|
func (d *DNSProvider) sendRequest(method string, resource string, payload interface{}) (*responseStruct, error) {
|
||||||
|
url := fmt.Sprintf("%s/%s", endpoint, resource)
|
||||||
|
|
||||||
|
body, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req, err := http.NewRequest(method, url, bytes.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
if len(d.apiKey) > 0 {
|
||||||
|
req.Header.Set("X-Api-Key", d.apiKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{Timeout: time.Duration(10 * time.Second)}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
return nil, fmt.Errorf("Gandi DNS: request failed with HTTP status code %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
var response responseStruct
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&response)
|
||||||
|
if err != nil && method != "DELETE" {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// functions to perform API actions
|
||||||
|
|
||||||
|
func (d *DNSProvider) addTXTRecord(domain string, name string, value string, ttl int) error {
|
||||||
|
target := fmt.Sprintf("domains/%s/records/%s/TXT", domain, name)
|
||||||
|
response, err := d.sendRequest("PUT", target, addFieldRequest{
|
||||||
|
RRSetTTL: ttl,
|
||||||
|
RRSetValues: []string{value},
|
||||||
|
})
|
||||||
|
if response != nil {
|
||||||
|
fmt.Printf("Gandi DNS: %s\n", response.Message)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DNSProvider) deleteTXTRecord(domain string, name string) error {
|
||||||
|
target := fmt.Sprintf("domains/%s/records/%s/TXT", domain, name)
|
||||||
|
response, err := d.sendRequest("DELETE", target, deleteFieldRequest{
|
||||||
|
Delete: true,
|
||||||
|
})
|
||||||
|
if response != nil && response.Message == "" {
|
||||||
|
fmt.Printf("Gandi DNS: Zone record deleted\n")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
11
vendor/github.com/xenolf/lego/providers/dns/pdns/pdns.go
generated
vendored
11
vendor/github.com/xenolf/lego/providers/dns/pdns/pdns.go
generated
vendored
|
@ -257,12 +257,11 @@ func (c *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawM
|
||||||
if c.host.Path != "/" {
|
if c.host.Path != "/" {
|
||||||
path = c.host.Path
|
path = c.host.Path
|
||||||
}
|
}
|
||||||
if c.apiVersion > 0 {
|
if !strings.HasPrefix(uri, "/") {
|
||||||
if !strings.HasPrefix(uri, "api/v") {
|
uri = "/" + uri
|
||||||
uri = "/api/v" + strconv.Itoa(c.apiVersion) + uri
|
}
|
||||||
} else {
|
if c.apiVersion > 0 && !strings.HasPrefix(uri, "/api/v") {
|
||||||
uri = "/" + uri
|
uri = "/api/v" + strconv.Itoa(c.apiVersion) + uri
|
||||||
}
|
|
||||||
}
|
}
|
||||||
url := c.host.Scheme + "://" + c.host.Host + path + uri
|
url := c.host.Scheme + "://" + c.host.Host + path + uri
|
||||||
req, err := http.NewRequest(method, url, body)
|
req, err := http.NewRequest(method, url, body)
|
||||||
|
|
Loading…
Reference in a new issue