forked from TrueCloudLab/lego
Merge branch 'master' into refactor/update-golangci-lint
This commit is contained in:
commit
4c346c9d92
162 changed files with 13309 additions and 1999 deletions
|
@ -117,6 +117,7 @@ git push -u origin my-feature
|
|||
| NIFCloud | `nifcloud` | [documentation](https://mbaas.nifcloud.com/doc/current/rest/common/format.html) | - |
|
||||
| NS1 | `ns1` | [documentation](https://ns1.com/api) | [Go client](https://github.com/ns1/ns1-go) |
|
||||
| Open Telekom Cloud | `otc` | [documentation](https://docs.otc.t-systems.com/en-us/dns/index.html) | - |
|
||||
| Oracle Cloud | `oraclecloud` | [documentation](https://docs.cloud.oracle.com/iaas/Content/DNS/Concepts/dnszonemanagement.htm) | [Go Client](https://github.com/oracle/oci-go-sdk) |
|
||||
| OVH | `ovh` | [documentation](https://eu.api.ovh.com/) | [Go client](https://github.com/ovh/go-ovh) |
|
||||
| PowerDNS | `pdns` | [documentation](https://doc.powerdns.com/md/httpapi/README/) | - |
|
||||
| Rackspace | `rackspace` | [documentation](https://developer.rackspace.com/docs/cloud-dns/v1/) | - |
|
||||
|
|
19
Gopkg.lock
generated
19
Gopkg.lock
generated
|
@ -192,12 +192,12 @@
|
|||
version = "v0.21.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e68d50b8dc605565eb62df1c2b2c67fa729e5b55aa1a6c81456eecbe0326ecdb"
|
||||
digest = "1:9013e4c7a6ff077dcb478aa75524aa73b5763136efb4efe8949b18d9b90dd212"
|
||||
name = "github.com/exoscale/egoscale"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "67368ae928a70cb5cb44ecf6f418ee33a1ade044"
|
||||
version = "v0.11.6"
|
||||
revision = "4acc53d7aa0960f007acf1daedef69a6d24d8d1f"
|
||||
version = "v0.14.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:aa3ed0a71c4e66e4ae6486bf97a3f4cab28edc78df2e50c5ad01dc7d91604b88"
|
||||
|
@ -379,6 +379,17 @@
|
|||
revision = "d8152159450570012552f924a0ae6ab3d8c617e0"
|
||||
version = "v0.6.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c665ac9fd8cedb7bea85380a441dec4e5de3c7d4574e18c6ba53dfe04cf50878"
|
||||
name = "github.com/oracle/oci-go-sdk"
|
||||
packages = [
|
||||
"common",
|
||||
"dns",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "f1ecb80f81a9cfa7dbfc964a34a3c62323277a9d"
|
||||
version = "v4.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:02584222c11b07d1d61cd76cc73e78cbc72810384a7ea69c543246d60d3335f7"
|
||||
|
@ -692,6 +703,8 @@
|
|||
"github.com/namedotcom/go/namecom",
|
||||
"github.com/nrdcg/auroradns",
|
||||
"github.com/nrdcg/goinwx",
|
||||
"github.com/oracle/oci-go-sdk/common",
|
||||
"github.com/oracle/oci-go-sdk/dns",
|
||||
"github.com/ovh/go-ovh/ovh",
|
||||
"github.com/rainycape/memcache",
|
||||
"github.com/sacloud/libsacloud/api",
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
name = "github.com/transip/gotransip"
|
||||
|
||||
[[constraint]]
|
||||
version = "0.11.1"
|
||||
version = "0.14.0"
|
||||
name = "github.com/exoscale/egoscale"
|
||||
|
||||
[[constraint]]
|
||||
|
@ -100,3 +100,8 @@
|
|||
[[constraint]]
|
||||
version = "v0.7.3"
|
||||
name = "github.com/akamai/AkamaiOPEN-edgegrid-golang"
|
||||
|
||||
[[constraint]]
|
||||
version = "4.0.0"
|
||||
name = "github.com/oracle/oci-go-sdk"
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ Here is an example bash command using the CloudFlare DNS provider:
|
|||
fmt.Fprintln(w, "\tnetcup:\tNETCUP_CUSTOMER_NUMBER, NETCUP_API_KEY, NETCUP_API_PASSWORD")
|
||||
fmt.Fprintln(w, "\tnifcloud:\tNIFCLOUD_ACCESS_KEY_ID, NIFCLOUD_SECRET_ACCESS_KEY")
|
||||
fmt.Fprintln(w, "\tns1:\tNS1_API_KEY")
|
||||
fmt.Fprintln(w, "\toraclecloud:\tOCI_PRIVKEY_BASE64, OCI_PRIVKEY_PASS, OCI_TENANCY_OCID, OCI_USER_OCID, OCI_PUBKEY_FINGERPRINT, OCI_REGION, OCI_COMPARTMENT_OCID")
|
||||
fmt.Fprintln(w, "\totc:\tOTC_USER_NAME, OTC_PASSWORD, OTC_PROJECT_NAME, OTC_DOMAIN_NAME, OTC_IDENTITY_ENDPOINT")
|
||||
fmt.Fprintln(w, "\tovh:\tOVH_ENDPOINT, OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY")
|
||||
fmt.Fprintln(w, "\tpdns:\tPDNS_API_KEY, PDNS_API_URL")
|
||||
|
@ -122,6 +123,7 @@ Here is an example bash command using the CloudFlare DNS provider:
|
|||
fmt.Fprintln(w, "\tnetcup:\tNETCUP_POLLING_INTERVAL, NETCUP_PROPAGATION_TIMEOUT, NETCUP_TTL, NETCUP_HTTP_TIMEOUT")
|
||||
fmt.Fprintln(w, "\tnifcloud:\tNIFCLOUD_POLLING_INTERVAL, NIFCLOUD_PROPAGATION_TIMEOUT, NIFCLOUD_TTL, NIFCLOUD_HTTP_TIMEOUT")
|
||||
fmt.Fprintln(w, "\tns1:\tNS1_POLLING_INTERVAL, NS1_PROPAGATION_TIMEOUT, NS1_TTL, NS1_HTTP_TIMEOUT")
|
||||
fmt.Fprintln(w, "\toraclecloud:\tOCI_TTL, OCI_PROPAGATION_TIMEOUT, OCI_POLLING_INTERVAL")
|
||||
fmt.Fprintln(w, "\totc:\tOTC_POLLING_INTERVAL, OTC_PROPAGATION_TIMEOUT, OTC_TTL, OTC_HTTP_TIMEOUT")
|
||||
fmt.Fprintln(w, "\tovh:\tOVH_POLLING_INTERVAL, OVH_PROPAGATION_TIMEOUT, OVH_TTL, OVH_HTTP_TIMEOUT")
|
||||
fmt.Fprintln(w, "\tpdns:\tPDNS_POLLING_INTERVAL, PDNS_PROPAGATION_TIMEOUT, PDNS_TTL, PDNS_HTTP_TIMEOUT")
|
||||
|
|
|
@ -42,6 +42,7 @@ import (
|
|||
"github.com/xenolf/lego/providers/dns/netcup"
|
||||
"github.com/xenolf/lego/providers/dns/nifcloud"
|
||||
"github.com/xenolf/lego/providers/dns/ns1"
|
||||
"github.com/xenolf/lego/providers/dns/oraclecloud"
|
||||
"github.com/xenolf/lego/providers/dns/otc"
|
||||
"github.com/xenolf/lego/providers/dns/ovh"
|
||||
"github.com/xenolf/lego/providers/dns/pdns"
|
||||
|
@ -137,6 +138,8 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) {
|
|||
return nifcloud.NewDNSProvider()
|
||||
case "ns1":
|
||||
return ns1.NewDNSProvider()
|
||||
case "oraclecloud":
|
||||
return oraclecloud.NewDNSProvider()
|
||||
case "otc":
|
||||
return otc.NewDNSProvider()
|
||||
case "ovh":
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
package exoscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
@ -12,7 +13,7 @@ import (
|
|||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
const defaultBaseURL = "https://api.exoscale.ch/dns"
|
||||
const defaultBaseURL = "https://api.exoscale.com/dns"
|
||||
|
||||
// Config is used to configure the creation of the DNSProvider
|
||||
type Config struct {
|
||||
|
@ -81,6 +82,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
|||
|
||||
// Present creates a TXT record to fulfill the dns-01 challenge.
|
||||
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||
ctx := context.Background()
|
||||
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||
zone, recordName, err := d.FindZoneAndRecordName(fqdn, domain)
|
||||
if err != nil {
|
||||
|
@ -100,7 +102,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||
RecordType: "TXT",
|
||||
}
|
||||
|
||||
_, err := d.client.CreateRecord(zone, record)
|
||||
_, err := d.client.CreateRecord(ctx, zone, record)
|
||||
if err != nil {
|
||||
return errors.New("Error while creating DNS record: " + err.Error())
|
||||
}
|
||||
|
@ -113,7 +115,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||
RecordType: "TXT",
|
||||
}
|
||||
|
||||
_, err := d.client.UpdateRecord(zone, record)
|
||||
_, err := d.client.UpdateRecord(ctx, zone, record)
|
||||
if err != nil {
|
||||
return errors.New("Error while updating DNS record: " + err.Error())
|
||||
}
|
||||
|
@ -124,6 +126,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||
|
||||
// CleanUp removes the record matching the specified parameters.
|
||||
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||
ctx := context.Background()
|
||||
fqdn, _ := dns01.GetRecord(domain, keyAuth)
|
||||
zone, recordName, err := d.FindZoneAndRecordName(fqdn, domain)
|
||||
if err != nil {
|
||||
|
@ -136,7 +139,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
|||
}
|
||||
|
||||
if recordID != 0 {
|
||||
err = d.client.DeleteRecord(zone, recordID)
|
||||
err = d.client.DeleteRecord(ctx, zone, recordID)
|
||||
if err != nil {
|
||||
return errors.New("Error while deleting DNS record: " + err.Error())
|
||||
}
|
||||
|
@ -154,7 +157,8 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
|||
// FindExistingRecordID Query Exoscale to find an existing record for this name.
|
||||
// Returns nil if no record could be found
|
||||
func (d *DNSProvider) FindExistingRecordID(zone, recordName string) (int64, error) {
|
||||
records, err := d.client.GetRecords(zone)
|
||||
ctx := context.Background()
|
||||
records, err := d.client.GetRecords(ctx, zone)
|
||||
if err != nil {
|
||||
return -1, errors.New("Error while retrievening DNS records: " + err.Error())
|
||||
}
|
||||
|
|
|
@ -2,112 +2,102 @@ package hostingde
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff"
|
||||
)
|
||||
|
||||
const defaultBaseURL = "https://secure.hosting.de/api/dns/v1/json"
|
||||
|
||||
// RecordsAddRequest represents a DNS record to add
|
||||
type RecordsAddRequest struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Content string `json:"content"`
|
||||
TTL int `json:"ttl"`
|
||||
}
|
||||
// https://www.hosting.de/api/?json#list-zoneconfigs
|
||||
func (d *DNSProvider) listZoneConfigs(findRequest ZoneConfigsFindRequest) (*ZoneConfigsFindResponse, error) {
|
||||
uri := defaultBaseURL + "/zoneConfigsFind"
|
||||
|
||||
// RecordsDeleteRequest represents a DNS record to remove
|
||||
type RecordsDeleteRequest struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Content string `json:"content"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
findResponse := &ZoneConfigsFindResponse{}
|
||||
|
||||
// ZoneConfigObject represents the ZoneConfig-section of a hosting.de API response.
|
||||
type ZoneConfigObject struct {
|
||||
AccountID string `json:"accountId"`
|
||||
EmailAddress string `json:"emailAddress"`
|
||||
ID string `json:"id"`
|
||||
LastChangeDate string `json:"lastChangeDate"`
|
||||
MasterIP string `json:"masterIp"`
|
||||
Name string `json:"name"`
|
||||
NameUnicode string `json:"nameUnicode"`
|
||||
SOAValues struct {
|
||||
Expire int `json:"expire"`
|
||||
NegativeTTL int `json:"negativeTtl"`
|
||||
Refresh int `json:"refresh"`
|
||||
Retry int `json:"retry"`
|
||||
Serial string `json:"serial"`
|
||||
TTL int `json:"ttl"`
|
||||
} `json:"soaValues"`
|
||||
Status string `json:"status"`
|
||||
TemplateValues string `json:"templateValues"`
|
||||
Type string `json:"type"`
|
||||
ZoneTransferWhitelist []string `json:"zoneTransferWhitelist"`
|
||||
}
|
||||
|
||||
// ZoneUpdateError represents an error in a ZoneUpdateResponse
|
||||
type ZoneUpdateError struct {
|
||||
Code int `json:"code"`
|
||||
ContextObject string `json:"contextObject"`
|
||||
ContextPath string `json:"contextPath"`
|
||||
Details []string `json:"details"`
|
||||
Text string `json:"text"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// ZoneUpdateMetadata represents the metadata in a ZoneUpdateResponse
|
||||
type ZoneUpdateMetadata struct {
|
||||
ClientTransactionID string `json:"clientTransactionId"`
|
||||
ServerTransactionID string `json:"serverTransactionId"`
|
||||
}
|
||||
|
||||
// ZoneUpdateResponse represents a response from hosting.de API
|
||||
type ZoneUpdateResponse struct {
|
||||
Errors []ZoneUpdateError `json:"errors"`
|
||||
Metadata ZoneUpdateMetadata `json:"metadata"`
|
||||
Warnings []string `json:"warnings"`
|
||||
Status string `json:"status"`
|
||||
Response struct {
|
||||
Records []struct {
|
||||
Content string `json:"content"`
|
||||
Type string `json:"type"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
LastChangeDate string `json:"lastChangeDate"`
|
||||
Priority int `json:"priority"`
|
||||
RecordTemplateID string `json:"recordTemplateId"`
|
||||
ZoneConfigID string `json:"zoneConfigId"`
|
||||
TTL int `json:"ttl"`
|
||||
} `json:"records"`
|
||||
ZoneConfig ZoneConfigObject `json:"zoneConfig"`
|
||||
} `json:"response"`
|
||||
}
|
||||
|
||||
// ZoneConfigSelector represents a "minimal" ZoneConfig object used in hosting.de API requests
|
||||
type ZoneConfigSelector struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// ZoneUpdateRequest represents a hosting.de API ZoneUpdate request
|
||||
type ZoneUpdateRequest struct {
|
||||
AuthToken string `json:"authToken"`
|
||||
ZoneConfigSelector `json:"zoneConfig"`
|
||||
RecordsToAdd []RecordsAddRequest `json:"recordsToAdd"`
|
||||
RecordsToDelete []RecordsDeleteRequest `json:"recordsToDelete"`
|
||||
}
|
||||
|
||||
func (d *DNSProvider) updateZone(updateRequest ZoneUpdateRequest) (*ZoneUpdateResponse, error) {
|
||||
body, err := json.Marshal(updateRequest)
|
||||
rawResp, err := d.post(uri, findRequest, findResponse)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, defaultBaseURL+"/zoneUpdate", bytes.NewReader(body))
|
||||
if len(findResponse.Response.Data) == 0 {
|
||||
return nil, fmt.Errorf("%v: %s", err, toUnreadableBodyMessage(uri, rawResp))
|
||||
}
|
||||
|
||||
if findResponse.Status != "success" && findResponse.Status != "pending" {
|
||||
return findResponse, errors.New(toUnreadableBodyMessage(uri, rawResp))
|
||||
}
|
||||
|
||||
return findResponse, nil
|
||||
}
|
||||
|
||||
// https://www.hosting.de/api/?json#updating-zones
|
||||
func (d *DNSProvider) updateZone(updateRequest ZoneUpdateRequest) (*ZoneUpdateResponse, error) {
|
||||
uri := defaultBaseURL + "/zoneUpdate"
|
||||
|
||||
// but we'll need the ID later to delete the record
|
||||
updateResponse := &ZoneUpdateResponse{}
|
||||
|
||||
rawResp, err := d.post(uri, updateRequest, updateResponse)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if updateResponse.Status != "success" && updateResponse.Status != "pending" {
|
||||
return nil, errors.New(toUnreadableBodyMessage(uri, rawResp))
|
||||
}
|
||||
|
||||
return updateResponse, nil
|
||||
}
|
||||
|
||||
func (d *DNSProvider) getZone(findRequest ZoneConfigsFindRequest) (*ZoneConfig, error) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
var zoneConfig *ZoneConfig
|
||||
|
||||
operation := func() error {
|
||||
findResponse, err := d.listZoneConfigs(findRequest)
|
||||
if err != nil {
|
||||
cancel()
|
||||
return err
|
||||
}
|
||||
|
||||
if findResponse.Response.Data[0].Status != "active" {
|
||||
return fmt.Errorf("unexpected status: %q", findResponse.Response.Data[0].Status)
|
||||
}
|
||||
|
||||
zoneConfig = &findResponse.Response.Data[0]
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
bo := backoff.NewExponentialBackOff()
|
||||
bo.InitialInterval = 3 * time.Second
|
||||
bo.MaxInterval = 10 * bo.InitialInterval
|
||||
bo.MaxElapsedTime = 100 * bo.InitialInterval
|
||||
|
||||
// retry in case the zone was edited recently and is not yet active
|
||||
err := backoff.Retry(operation, backoff.WithContext(bo, ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return zoneConfig, nil
|
||||
}
|
||||
|
||||
func (d *DNSProvider) post(uri string, request interface{}, response interface{}) ([]byte, error) {
|
||||
body, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, uri, bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -121,23 +111,17 @@ func (d *DNSProvider) updateZone(updateRequest ZoneUpdateRequest) (*ZoneUpdateRe
|
|||
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, errors.New(toUnreadableBodyMessage(req, content))
|
||||
return nil, errors.New(toUnreadableBodyMessage(uri, content))
|
||||
}
|
||||
|
||||
// Everything looks good; but we'll need the ID later to delete the record
|
||||
updateResponse := &ZoneUpdateResponse{}
|
||||
err = json.Unmarshal(content, updateResponse)
|
||||
err = json.Unmarshal(content, response)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v: %s", err, toUnreadableBodyMessage(req, content))
|
||||
return nil, fmt.Errorf("%v: %s", err, toUnreadableBodyMessage(uri, content))
|
||||
}
|
||||
|
||||
if updateResponse.Status != "success" && updateResponse.Status != "pending" {
|
||||
return updateResponse, errors.New(toUnreadableBodyMessage(req, content))
|
||||
}
|
||||
|
||||
return updateResponse, nil
|
||||
return content, nil
|
||||
}
|
||||
|
||||
func toUnreadableBodyMessage(req *http.Request, rawBody []byte) string {
|
||||
return fmt.Sprintf("the request %s sent a response with a body which is an invalid format: %q", req.URL, string(rawBody))
|
||||
func toUnreadableBodyMessage(uri string, rawBody []byte) string {
|
||||
return fmt.Sprintf("the request %s sent a response with a body which is an invalid format: %q", uri, string(rawBody))
|
||||
}
|
||||
|
|
|
@ -87,7 +87,24 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
|
|||
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||
|
||||
rec := []RecordsAddRequest{{
|
||||
// get the ZoneConfig for that domain
|
||||
zonesFind := ZoneConfigsFindRequest{
|
||||
Filter: Filter{
|
||||
Field: "zoneName",
|
||||
Value: domain,
|
||||
},
|
||||
Limit: 1,
|
||||
Page: 1,
|
||||
}
|
||||
zonesFind.AuthToken = d.config.APIKey
|
||||
|
||||
zoneConfig, err := d.getZone(zonesFind)
|
||||
if err != nil {
|
||||
return fmt.Errorf("hostingde: %v", err)
|
||||
}
|
||||
zoneConfig.Name = d.config.ZoneName
|
||||
|
||||
rec := []DNSRecord{{
|
||||
Type: "TXT",
|
||||
Name: dns01.UnFqdn(fqdn),
|
||||
Content: value,
|
||||
|
@ -95,12 +112,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||
}}
|
||||
|
||||
req := ZoneUpdateRequest{
|
||||
AuthToken: d.config.APIKey,
|
||||
ZoneConfigSelector: ZoneConfigSelector{
|
||||
Name: d.config.ZoneName,
|
||||
},
|
||||
ZoneConfig: *zoneConfig,
|
||||
RecordsToAdd: rec,
|
||||
}
|
||||
req.AuthToken = d.config.APIKey
|
||||
|
||||
resp, err := d.updateZone(req)
|
||||
if err != nil {
|
||||
|
@ -126,35 +141,41 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||
|
||||
// get the record's unique ID from when we created it
|
||||
d.recordIDsMu.Lock()
|
||||
recordID, ok := d.recordIDs[fqdn]
|
||||
d.recordIDsMu.Unlock()
|
||||
if !ok {
|
||||
return fmt.Errorf("hostingde: unknown record ID for %q", fqdn)
|
||||
}
|
||||
|
||||
rec := []RecordsDeleteRequest{{
|
||||
rec := []DNSRecord{{
|
||||
Type: "TXT",
|
||||
Name: dns01.UnFqdn(fqdn),
|
||||
Content: value,
|
||||
ID: recordID,
|
||||
Content: `"` + value + `"`,
|
||||
}}
|
||||
|
||||
req := ZoneUpdateRequest{
|
||||
AuthToken: d.config.APIKey,
|
||||
ZoneConfigSelector: ZoneConfigSelector{
|
||||
Name: d.config.ZoneName,
|
||||
// get the ZoneConfig for that domain
|
||||
zonesFind := ZoneConfigsFindRequest{
|
||||
Filter: Filter{
|
||||
Field: "zoneName",
|
||||
Value: domain,
|
||||
},
|
||||
Limit: 1,
|
||||
Page: 1,
|
||||
}
|
||||
zonesFind.AuthToken = d.config.APIKey
|
||||
|
||||
zoneConfig, err := d.getZone(zonesFind)
|
||||
if err != nil {
|
||||
return fmt.Errorf("hostingde: %v", err)
|
||||
}
|
||||
zoneConfig.Name = d.config.ZoneName
|
||||
|
||||
req := ZoneUpdateRequest{
|
||||
ZoneConfig: *zoneConfig,
|
||||
RecordsToDelete: rec,
|
||||
}
|
||||
req.AuthToken = d.config.APIKey
|
||||
|
||||
// Delete record ID from map
|
||||
d.recordIDsMu.Lock()
|
||||
delete(d.recordIDs, fqdn)
|
||||
d.recordIDsMu.Unlock()
|
||||
|
||||
_, err := d.updateZone(req)
|
||||
_, err = d.updateZone(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("hostingde: %v", err)
|
||||
}
|
||||
|
|
139
providers/dns/hostingde/model.go
Normal file
139
providers/dns/hostingde/model.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
package hostingde
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// APIError represents an error in an API response.
|
||||
// https://www.hosting.de/api/?json#warnings-and-errors
|
||||
type APIError struct {
|
||||
Code int `json:"code"`
|
||||
ContextObject string `json:"contextObject"`
|
||||
ContextPath string `json:"contextPath"`
|
||||
Details []string `json:"details"`
|
||||
Text string `json:"text"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// Filter is used to filter FindRequests to the API.
|
||||
// https://www.hosting.de/api/?json#filter-object
|
||||
type Filter struct {
|
||||
Field string `json:"field"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// Sort is used to sort FindRequests from the API.
|
||||
// https://www.hosting.de/api/?json#filtering-and-sorting
|
||||
type Sort struct {
|
||||
Field string `json:"zoneName"`
|
||||
Order string `json:"order"`
|
||||
}
|
||||
|
||||
// Metadata represents the metadata in an API response.
|
||||
// https://www.hosting.de/api/?json#metadata-object
|
||||
type Metadata struct {
|
||||
ClientTransactionID string `json:"clientTransactionId"`
|
||||
ServerTransactionID string `json:"serverTransactionId"`
|
||||
}
|
||||
|
||||
// ZoneConfig The ZoneConfig object defines a zone.
|
||||
// https://www.hosting.de/api/?json#the-zoneconfig-object
|
||||
type ZoneConfig struct {
|
||||
ID string `json:"id"`
|
||||
AccountID string `json:"accountId"`
|
||||
Status string `json:"status"`
|
||||
Name string `json:"name"`
|
||||
NameUnicode string `json:"nameUnicode"`
|
||||
MasterIP string `json:"masterIp"`
|
||||
Type string `json:"type"`
|
||||
EMailAddress string `json:"emailAddress"`
|
||||
ZoneTransferWhitelist []string `json:"zoneTransferWhitelist"`
|
||||
LastChangeDate string `json:"lastChangeDate"`
|
||||
DNSServerGroupID string `json:"dnsServerGroupId"`
|
||||
DNSSecMode string `json:"dnsSecMode"`
|
||||
SOAValues *SOAValues `json:"soaValues,omitempty"`
|
||||
TemplateValues json.RawMessage `json:"templateValues,omitempty"`
|
||||
}
|
||||
|
||||
// SOAValues The SOA values object contains the time (seconds) used in a zone’s SOA record.
|
||||
// https://www.hosting.de/api/?json#the-soa-values-object
|
||||
type SOAValues struct {
|
||||
Refresh int `json:"refresh"`
|
||||
Retry int `json:"retry"`
|
||||
Expire int `json:"expire"`
|
||||
TTL int `json:"ttl"`
|
||||
NegativeTTL int `json:"negativeTtl"`
|
||||
}
|
||||
|
||||
// DNSRecord The DNS Record object is part of a zone. It is used to manage DNS resource records.
|
||||
// https://www.hosting.de/api/?json#the-record-object
|
||||
type DNSRecord struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
ZoneID string `json:"zoneId,omitempty"`
|
||||
RecordTemplateID string `json:"recordTemplateId,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
TTL int `json:"ttl,omitempty"`
|
||||
Priority int `json:"priority,omitempty"`
|
||||
LastChangeDate string `json:"lastChangeDate,omitempty"`
|
||||
}
|
||||
|
||||
// Zone The Zone Object.
|
||||
// https://www.hosting.de/api/?json#the-zone-object
|
||||
type Zone struct {
|
||||
Records []DNSRecord `json:"records"`
|
||||
ZoneConfig ZoneConfig `json:"zoneConfig"`
|
||||
}
|
||||
|
||||
// ZoneUpdateRequest represents a API ZoneUpdate request.
|
||||
// https://www.hosting.de/api/?json#updating-zones
|
||||
type ZoneUpdateRequest struct {
|
||||
BaseRequest
|
||||
ZoneConfig `json:"zoneConfig"`
|
||||
RecordsToAdd []DNSRecord `json:"recordsToAdd"`
|
||||
RecordsToDelete []DNSRecord `json:"recordsToDelete"`
|
||||
}
|
||||
|
||||
// ZoneUpdateResponse represents a response from the API.
|
||||
// https://www.hosting.de/api/?json#updating-zones
|
||||
type ZoneUpdateResponse struct {
|
||||
BaseResponse
|
||||
Response Zone `json:"response"`
|
||||
}
|
||||
|
||||
// ZoneConfigsFindRequest represents a API ZonesFind request.
|
||||
// https://www.hosting.de/api/?json#list-zoneconfigs
|
||||
type ZoneConfigsFindRequest struct {
|
||||
BaseRequest
|
||||
Filter Filter `json:"filter"`
|
||||
Limit int `json:"limit"`
|
||||
Page int `json:"page"`
|
||||
Sort *Sort `json:"sort,omitempty"`
|
||||
}
|
||||
|
||||
// ZoneConfigsFindResponse represents the API response for ZoneConfigsFind.
|
||||
// https://www.hosting.de/api/?json#list-zoneconfigs
|
||||
type ZoneConfigsFindResponse struct {
|
||||
BaseResponse
|
||||
Response struct {
|
||||
Limit int `json:"limit"`
|
||||
Page int `json:"page"`
|
||||
TotalEntries int `json:"totalEntries"`
|
||||
TotalPages int `json:"totalPages"`
|
||||
Type string `json:"type"`
|
||||
Data []ZoneConfig `json:"data"`
|
||||
} `json:"response"`
|
||||
}
|
||||
|
||||
// BaseResponse Common response struct.
|
||||
// https://www.hosting.de/api/?json#responses
|
||||
type BaseResponse struct {
|
||||
Errors []APIError `json:"errors"`
|
||||
Metadata Metadata `json:"metadata"`
|
||||
Warnings []string `json:"warnings"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
// BaseRequest Common request struct.
|
||||
type BaseRequest struct {
|
||||
AuthToken string `json:"authToken"`
|
||||
}
|
28
providers/dns/oraclecloud/README.md
Normal file
28
providers/dns/oraclecloud/README.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Export shell-env for OracleCloud
|
||||
|
||||
in Bash
|
||||
|
||||
```
|
||||
export OCI_PRIVKEY_BASE64=`base64 ~/.oci/oci_api_key.pem`
|
||||
export OCI_PRIVKEY_PASS="secret"
|
||||
export OCI_TENANCY_OCID="ocid1.tenancy.oc1..secret"
|
||||
export OCI_USER_OCID="ocid1.user.oc1..secret"
|
||||
export OCI_PUBKEY_FINGERPRINT="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"
|
||||
export OCI_REGION="us-phoenix-1"
|
||||
export OCI_COMPARTMENT_OCID="ocid1.tenancy.oc1..secret"
|
||||
```
|
||||
|
||||
in Fish
|
||||
|
||||
```
|
||||
set IFS
|
||||
set -x OCI_PRIVKEY_BASE64 (base64 ~/.oci/oci_api_key.pem)
|
||||
set IFS \n" "\t
|
||||
|
||||
set -x OCI_PRIVKEY_PASS 'secret'
|
||||
set -x OCI_TENANCY_OCID 'ocid1.tenancy.oc1..secret'
|
||||
set -x OCI_USER_OCID 'ocid1.user.oc1..secret'
|
||||
set -x OCI_PUBKEY_FINGERPRINT '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00'
|
||||
set -x OCI_REGION 'us-phoenix-1'
|
||||
set -x OCI_COMPARTMENT_OCID 'ocid1.tenancy.oc1..secret'
|
||||
```
|
75
providers/dns/oraclecloud/configprovider.go
Normal file
75
providers/dns/oraclecloud/configprovider.go
Normal file
|
@ -0,0 +1,75 @@
|
|||
package oraclecloud
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
||||
"github.com/oracle/oci-go-sdk/common"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
const (
|
||||
ociPrivkeyBase64 = "OCI_PRIVKEY_BASE64"
|
||||
ociPrivkeyPass = "OCI_PRIVKEY_PASS"
|
||||
ociTenancyOCID = "OCI_TENANCY_OCID"
|
||||
ociUserOCID = "OCI_USER_OCID"
|
||||
ociPubkeyFingerprint = "OCI_PUBKEY_FINGERPRINT"
|
||||
ociRegion = "OCI_REGION"
|
||||
)
|
||||
|
||||
type configProvider struct {
|
||||
values map[string]string
|
||||
privateKeyPassphrase string
|
||||
}
|
||||
|
||||
func newConfigProvider(values map[string]string) *configProvider {
|
||||
return &configProvider{
|
||||
values: values,
|
||||
privateKeyPassphrase: env.GetOrFile(ociPrivkeyPass),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *configProvider) PrivateRSAKey() (*rsa.PrivateKey, error) {
|
||||
privateKeyDecoded, err := base64.StdEncoding.DecodeString(p.values[ociPrivkeyBase64])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return common.PrivateKeyFromBytes(privateKeyDecoded, common.String(p.privateKeyPassphrase))
|
||||
}
|
||||
|
||||
func (p *configProvider) KeyID() (string, error) {
|
||||
tenancy, err := p.TenancyOCID()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
user, err := p.UserOCID()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
fingerprint, err := p.KeyFingerprint()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s/%s", tenancy, user, fingerprint), nil
|
||||
}
|
||||
|
||||
func (p *configProvider) TenancyOCID() (value string, err error) {
|
||||
return p.values[ociTenancyOCID], nil
|
||||
}
|
||||
|
||||
func (p *configProvider) UserOCID() (string, error) {
|
||||
return p.values[ociUserOCID], nil
|
||||
}
|
||||
|
||||
func (p *configProvider) KeyFingerprint() (string, error) {
|
||||
return p.values[ociPubkeyFingerprint], nil
|
||||
}
|
||||
|
||||
func (p *configProvider) Region() (string, error) {
|
||||
return p.values[ociRegion], nil
|
||||
}
|
169
providers/dns/oraclecloud/oraclecloud.go
Normal file
169
providers/dns/oraclecloud/oraclecloud.go
Normal file
|
@ -0,0 +1,169 @@
|
|||
package oraclecloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/oracle/oci-go-sdk/common"
|
||||
"github.com/oracle/oci-go-sdk/dns"
|
||||
"github.com/xenolf/lego/challenge/dns01"
|
||||
"github.com/xenolf/lego/platform/config/env"
|
||||
)
|
||||
|
||||
// Config is used to configure the creation of the DNSProvider
|
||||
type Config struct {
|
||||
CompartmentID string
|
||||
OCIConfigProvider common.ConfigurationProvider
|
||||
PropagationTimeout time.Duration
|
||||
PollingInterval time.Duration
|
||||
TTL int
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
// NewDefaultConfig returns a default configuration for the DNSProvider
|
||||
func NewDefaultConfig() *Config {
|
||||
return &Config{
|
||||
TTL: env.GetOrDefaultInt("OCI_TTL", dns01.DefaultTTL),
|
||||
PropagationTimeout: env.GetOrDefaultSecond("OCI_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout),
|
||||
PollingInterval: env.GetOrDefaultSecond("OCI_POLLING_INTERVAL", dns01.DefaultPollingInterval),
|
||||
HTTPClient: &http.Client{
|
||||
Timeout: env.GetOrDefaultSecond("OCI_HTTP_TIMEOUT", 60*time.Second),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// DNSProvider is an implementation of the acme.ChallengeProvider interface.
|
||||
type DNSProvider struct {
|
||||
client *dns.DnsClient
|
||||
config *Config
|
||||
}
|
||||
|
||||
// NewDNSProvider returns a DNSProvider instance configured for OracleCloud.
|
||||
func NewDNSProvider() (*DNSProvider, error) {
|
||||
values, err := env.Get(ociPrivkeyBase64, ociTenancyOCID, ociUserOCID, ociPubkeyFingerprint, ociRegion, "OCI_COMPARTMENT_OCID")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("oraclecloud: %v", err)
|
||||
}
|
||||
|
||||
config := NewDefaultConfig()
|
||||
config.CompartmentID = values["OCI_COMPARTMENT_OCID"]
|
||||
config.OCIConfigProvider = newConfigProvider(values)
|
||||
|
||||
return NewDNSProviderConfig(config)
|
||||
}
|
||||
|
||||
// NewDNSProviderConfig return a DNSProvider instance configured for OracleCloud.
|
||||
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||
if config == nil {
|
||||
return nil, errors.New("oraclecloud: the configuration of the DNS provider is nil")
|
||||
}
|
||||
|
||||
if config.CompartmentID == "" {
|
||||
return nil, errors.New("oraclecloud: CompartmentID is missing")
|
||||
}
|
||||
|
||||
if config.OCIConfigProvider == nil {
|
||||
return nil, errors.New("oraclecloud: OCIConfigProvider is missing")
|
||||
}
|
||||
|
||||
client, err := dns.NewDnsClientWithConfigurationProvider(config.OCIConfigProvider)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("oraclecloud: %v", err)
|
||||
}
|
||||
|
||||
if config.HTTPClient != nil {
|
||||
client.HTTPClient = config.HTTPClient
|
||||
}
|
||||
|
||||
return &DNSProvider{client: &client, config: config}, nil
|
||||
}
|
||||
|
||||
// Present creates a TXT record to fulfill the dns-01 challenge
|
||||
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||
|
||||
// generate request to dns.PatchDomainRecordsRequest
|
||||
recordOperation := dns.RecordOperation{
|
||||
Domain: common.String(dns01.UnFqdn(fqdn)),
|
||||
Rdata: common.String(value),
|
||||
Rtype: common.String("TXT"),
|
||||
Ttl: common.Int(30),
|
||||
IsProtected: common.Bool(false),
|
||||
}
|
||||
|
||||
request := dns.PatchDomainRecordsRequest{
|
||||
CompartmentId: common.String(d.config.CompartmentID),
|
||||
ZoneNameOrId: common.String(domain),
|
||||
Domain: common.String(dns01.UnFqdn(fqdn)),
|
||||
PatchDomainRecordsDetails: dns.PatchDomainRecordsDetails{
|
||||
Items: []dns.RecordOperation{recordOperation},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := d.client.PatchDomainRecords(context.Background(), request)
|
||||
if err != nil {
|
||||
return fmt.Errorf("oraclecloud: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanUp removes the TXT record matching the specified parameters
|
||||
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||
|
||||
// search to TXT record's hash to delete
|
||||
getRequest := dns.GetDomainRecordsRequest{
|
||||
ZoneNameOrId: common.String(domain),
|
||||
Domain: common.String(dns01.UnFqdn(fqdn)),
|
||||
CompartmentId: common.String(d.config.CompartmentID),
|
||||
Rtype: common.String("TXT"),
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
domainRecords, err := d.client.GetDomainRecords(ctx, getRequest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("oraclecloud: %v", err)
|
||||
}
|
||||
|
||||
if *domainRecords.OpcTotalItems == 0 {
|
||||
return fmt.Errorf("oraclecloud: no record to CleanUp")
|
||||
}
|
||||
|
||||
var deleteHash *string
|
||||
for _, record := range domainRecords.RecordCollection.Items {
|
||||
if record.Rdata != nil && *record.Rdata == `"`+value+`"` {
|
||||
deleteHash = record.RecordHash
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if deleteHash == nil {
|
||||
return fmt.Errorf("oraclecloud: no record to CleanUp")
|
||||
}
|
||||
|
||||
recordOperation := dns.RecordOperation{
|
||||
RecordHash: deleteHash,
|
||||
Operation: dns.RecordOperationOperationRemove,
|
||||
}
|
||||
|
||||
patchRequest := dns.PatchDomainRecordsRequest{
|
||||
ZoneNameOrId: common.String(domain),
|
||||
Domain: common.String(dns01.UnFqdn(fqdn)),
|
||||
PatchDomainRecordsDetails: dns.PatchDomainRecordsDetails{
|
||||
Items: []dns.RecordOperation{recordOperation},
|
||||
},
|
||||
CompartmentId: common.String(d.config.CompartmentID),
|
||||
}
|
||||
|
||||
_, err = d.client.PatchDomainRecords(ctx, patchRequest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("oraclecloud: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
268
providers/dns/oraclecloud/oraclecloud_test.go
Normal file
268
providers/dns/oraclecloud/oraclecloud_test.go
Normal file
|
@ -0,0 +1,268 @@
|
|||
package oraclecloud
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/oracle/oci-go-sdk/common"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/xenolf/lego/platform/tester"
|
||||
)
|
||||
|
||||
var envTest = tester.NewEnvTest(
|
||||
ociPrivkeyBase64,
|
||||
ociPrivkeyPass,
|
||||
ociTenancyOCID,
|
||||
ociUserOCID,
|
||||
ociPubkeyFingerprint,
|
||||
ociRegion,
|
||||
"OCI_COMPARTMENT_OCID").
|
||||
WithDomain("ORACLECLOUD_DOMAIN")
|
||||
|
||||
func TestNewDNSProvider(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
envVars map[string]string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "success",
|
||||
envVars: map[string]string{
|
||||
ociPrivkeyBase64: mustGeneratePrivateKey("secret1"),
|
||||
ociPrivkeyPass: "secret1",
|
||||
ociTenancyOCID: "ocid1.tenancy.oc1..secret",
|
||||
ociUserOCID: "ocid1.user.oc1..secret",
|
||||
ociPubkeyFingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
||||
ociRegion: "us-phoenix-1",
|
||||
"OCI_COMPARTMENT_OCID": "123",
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "missing credentials",
|
||||
envVars: map[string]string{},
|
||||
expected: "oraclecloud: some credentials information are missing: OCI_PRIVKEY_BASE64,OCI_TENANCY_OCID,OCI_USER_OCID,OCI_PUBKEY_FINGERPRINT,OCI_REGION,OCI_COMPARTMENT_OCID",
|
||||
},
|
||||
{
|
||||
desc: "missing CompartmentID",
|
||||
envVars: map[string]string{
|
||||
ociPrivkeyBase64: mustGeneratePrivateKey("secret"),
|
||||
ociPrivkeyPass: "secret",
|
||||
ociTenancyOCID: "ocid1.tenancy.oc1..secret",
|
||||
ociUserOCID: "ocid1.user.oc1..secret",
|
||||
ociPubkeyFingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
||||
ociRegion: "us-phoenix-1",
|
||||
"OCI_COMPARTMENT_OCID": "",
|
||||
},
|
||||
expected: "oraclecloud: some credentials information are missing: OCI_COMPARTMENT_OCID",
|
||||
},
|
||||
{
|
||||
desc: "missing OCI_PRIVKEY_BASE64",
|
||||
envVars: map[string]string{
|
||||
ociPrivkeyBase64: "",
|
||||
ociPrivkeyPass: "secret",
|
||||
ociTenancyOCID: "ocid1.tenancy.oc1..secret",
|
||||
ociUserOCID: "ocid1.user.oc1..secret",
|
||||
ociPubkeyFingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
||||
ociRegion: "us-phoenix-1",
|
||||
"OCI_COMPARTMENT_OCID": "123",
|
||||
},
|
||||
expected: "oraclecloud: some credentials information are missing: OCI_PRIVKEY_BASE64",
|
||||
},
|
||||
{
|
||||
desc: "missing OCI_PRIVKEY_PASS",
|
||||
envVars: map[string]string{
|
||||
ociPrivkeyBase64: mustGeneratePrivateKey("secret"),
|
||||
ociPrivkeyPass: "",
|
||||
ociTenancyOCID: "ocid1.tenancy.oc1..secret",
|
||||
ociUserOCID: "ocid1.user.oc1..secret",
|
||||
ociPubkeyFingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
||||
ociRegion: "us-phoenix-1",
|
||||
"OCI_COMPARTMENT_OCID": "123",
|
||||
},
|
||||
expected: "oraclecloud: can not create client, bad configuration: x509: decryption password incorrect",
|
||||
},
|
||||
{
|
||||
desc: "missing OCI_TENANCY_OCID",
|
||||
envVars: map[string]string{
|
||||
ociPrivkeyBase64: mustGeneratePrivateKey("secret"),
|
||||
ociPrivkeyPass: "secret",
|
||||
ociTenancyOCID: "",
|
||||
ociUserOCID: "ocid1.user.oc1..secret",
|
||||
ociPubkeyFingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
||||
ociRegion: "us-phoenix-1",
|
||||
"OCI_COMPARTMENT_OCID": "123",
|
||||
},
|
||||
expected: "oraclecloud: some credentials information are missing: OCI_TENANCY_OCID",
|
||||
},
|
||||
{
|
||||
desc: "missing OCI_USER_OCID",
|
||||
envVars: map[string]string{
|
||||
ociPrivkeyBase64: mustGeneratePrivateKey("secret"),
|
||||
ociPrivkeyPass: "secret",
|
||||
ociTenancyOCID: "ocid1.tenancy.oc1..secret",
|
||||
ociUserOCID: "",
|
||||
ociPubkeyFingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
||||
ociRegion: "us-phoenix-1",
|
||||
"OCI_COMPARTMENT_OCID": "123",
|
||||
},
|
||||
expected: "oraclecloud: some credentials information are missing: OCI_USER_OCID",
|
||||
},
|
||||
{
|
||||
desc: "missing OCI_PUBKEY_FINGERPRINT",
|
||||
envVars: map[string]string{
|
||||
ociPrivkeyBase64: mustGeneratePrivateKey("secret"),
|
||||
ociPrivkeyPass: "secret",
|
||||
ociTenancyOCID: "ocid1.tenancy.oc1..secret",
|
||||
ociUserOCID: "ocid1.user.oc1..secret",
|
||||
ociPubkeyFingerprint: "",
|
||||
ociRegion: "us-phoenix-1",
|
||||
"OCI_COMPARTMENT_OCID": "123",
|
||||
},
|
||||
expected: "oraclecloud: some credentials information are missing: OCI_PUBKEY_FINGERPRINT",
|
||||
},
|
||||
{
|
||||
desc: "missing OCI_REGION",
|
||||
envVars: map[string]string{
|
||||
ociPrivkeyBase64: mustGeneratePrivateKey("secret"),
|
||||
ociPrivkeyPass: "secret",
|
||||
ociTenancyOCID: "ocid1.tenancy.oc1..secret",
|
||||
ociUserOCID: "ocid1.user.oc1..secret",
|
||||
ociPubkeyFingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
||||
ociRegion: "",
|
||||
"OCI_COMPARTMENT_OCID": "123",
|
||||
},
|
||||
expected: "oraclecloud: some credentials information are missing: OCI_REGION",
|
||||
},
|
||||
{
|
||||
desc: "missing OCI_REGION",
|
||||
envVars: map[string]string{
|
||||
ociPrivkeyBase64: mustGeneratePrivateKey("secret"),
|
||||
ociPrivkeyPass: "secret",
|
||||
ociTenancyOCID: "ocid1.tenancy.oc1..secret",
|
||||
ociUserOCID: "ocid1.user.oc1..secret",
|
||||
ociPubkeyFingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
||||
ociRegion: "",
|
||||
"OCI_COMPARTMENT_OCID": "123",
|
||||
},
|
||||
expected: "oraclecloud: some credentials information are missing: OCI_REGION",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
defer envTest.RestoreEnv()
|
||||
envTest.ClearEnv()
|
||||
|
||||
envTest.Apply(test.envVars)
|
||||
|
||||
p, err := NewDNSProvider()
|
||||
|
||||
if len(test.expected) == 0 {
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, p)
|
||||
require.NotNil(t, p.config)
|
||||
require.NotNil(t, p.client)
|
||||
} else {
|
||||
require.EqualError(t, err, test.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDNSProviderConfig(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
compartmentID string
|
||||
configurationProvider common.ConfigurationProvider
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "invalid configuration",
|
||||
configurationProvider: &configProvider{},
|
||||
compartmentID: "123",
|
||||
expected: "oraclecloud: can not create client, bad configuration: PEM data was not found in buffer",
|
||||
},
|
||||
{
|
||||
desc: "OCIConfigProvider is missing",
|
||||
compartmentID: "123",
|
||||
expected: "oraclecloud: OCIConfigProvider is missing",
|
||||
},
|
||||
{
|
||||
desc: "missing CompartmentID",
|
||||
expected: "oraclecloud: CompartmentID is missing",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
config := NewDefaultConfig()
|
||||
config.CompartmentID = test.compartmentID
|
||||
config.OCIConfigProvider = test.configurationProvider
|
||||
|
||||
p, err := NewDNSProviderConfig(config)
|
||||
|
||||
if len(test.expected) == 0 {
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, p)
|
||||
require.NotNil(t, p.config)
|
||||
require.NotNil(t, p.client)
|
||||
} else {
|
||||
require.EqualError(t, err, test.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLivePresent(t *testing.T) {
|
||||
if !envTest.IsLiveTest() {
|
||||
t.Skip("skipping live test")
|
||||
}
|
||||
|
||||
envTest.RestoreEnv()
|
||||
provider, err := NewDNSProvider()
|
||||
require.NoError(t, err)
|
||||
|
||||
err = provider.Present(envTest.GetDomain(), "", "123d==")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestLiveCleanUp(t *testing.T) {
|
||||
if !envTest.IsLiveTest() {
|
||||
t.Skip("skipping live test")
|
||||
}
|
||||
|
||||
envTest.RestoreEnv()
|
||||
provider, err := NewDNSProvider()
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
err = provider.CleanUp(envTest.GetDomain(), "", "123d==")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func mustGeneratePrivateKey(pwd string) string {
|
||||
key, err := rsa.GenerateKey(rand.Reader, 512)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
block := &pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(key),
|
||||
}
|
||||
|
||||
if pwd != "" {
|
||||
block, err = x509.EncryptPEMBlock(rand.Reader, block.Type, block.Bytes, []byte(pwd), x509.PEMCipherAES256)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return base64.StdEncoding.EncodeToString(pem.EncodeToMemory(block))
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Domain represents domain name.
|
||||
|
@ -65,7 +66,9 @@ func NewClient(opts ClientOpts) *Client {
|
|||
}
|
||||
}
|
||||
|
||||
// GetDomainByName gets Domain object by its name.
|
||||
// GetDomainByName gets Domain object by its name. If `domainName` level > 2 and there is
|
||||
// no such domain on the account - it'll recursively search for the first
|
||||
// which is exists in Selectel Domain API.
|
||||
func (c *Client) GetDomainByName(domainName string) (*Domain, error) {
|
||||
uri := fmt.Sprintf("/%s", domainName)
|
||||
req, err := c.newRequest(http.MethodGet, uri, nil)
|
||||
|
@ -74,10 +77,17 @@ func (c *Client) GetDomainByName(domainName string) (*Domain, error) {
|
|||
}
|
||||
|
||||
domain := &Domain{}
|
||||
_, err = c.do(req, domain)
|
||||
resp, err := c.do(req, domain)
|
||||
if err != nil {
|
||||
switch {
|
||||
case resp.StatusCode == http.StatusNotFound && strings.Count(domainName, ".") > 1:
|
||||
// Look up for the next sub domain
|
||||
subIndex := strings.Index(domainName, ".")
|
||||
return c.GetDomainByName(domainName[subIndex+1:])
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return domain, nil
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Domain represents domain name.
|
||||
|
@ -65,7 +66,9 @@ func NewClient(opts ClientOpts) *Client {
|
|||
}
|
||||
}
|
||||
|
||||
// GetDomainByName gets Domain object by its name.
|
||||
// GetDomainByName gets Domain object by its name. If `domainName` level > 2 and there is
|
||||
// no such domain on the account - it'll recursively search for the first
|
||||
// which is exists in Vscale Domains API.
|
||||
func (c *Client) GetDomainByName(domainName string) (*Domain, error) {
|
||||
uri := fmt.Sprintf("/%s", domainName)
|
||||
req, err := c.newRequest(http.MethodGet, uri, nil)
|
||||
|
@ -74,10 +77,17 @@ func (c *Client) GetDomainByName(domainName string) (*Domain, error) {
|
|||
}
|
||||
|
||||
domain := &Domain{}
|
||||
_, err = c.do(req, domain)
|
||||
resp, err := c.do(req, domain)
|
||||
if err != nil {
|
||||
switch {
|
||||
case resp.StatusCode == http.StatusNotFound && strings.Count(domainName, ".") > 1:
|
||||
// Look up for the next sub domain
|
||||
subIndex := strings.Index(domainName, ".")
|
||||
return c.GetDomainByName(domainName[subIndex+1:])
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return domain, nil
|
||||
}
|
||||
|
|
91
vendor/github.com/exoscale/egoscale/accounts.go
generated
vendored
91
vendor/github.com/exoscale/egoscale/accounts.go
generated
vendored
|
@ -1,32 +1,12 @@
|
|||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// 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 int16
|
||||
|
||||
//go:generate stringer -type AccountType
|
||||
const (
|
||||
// UserAccount represents a User
|
||||
UserAccount AccountType = 0
|
||||
// AdminAccount represents an Admin
|
||||
AdminAccount AccountType = 1
|
||||
// DomainAdminAccount represents a Domain Admin
|
||||
DomainAdminAccount AccountType = 2
|
||||
)
|
||||
|
||||
// Account provides the detailed account information
|
||||
type Account struct {
|
||||
AccountDetails map[string]string `json:"accountdetails,omitempty" doc:"details for the account"`
|
||||
AccountType AccountType `json:"accounttype,omitempty" doc:"account type (admin, domain-admin, user)"`
|
||||
CPUAvailable string `json:"cpuavailable,omitempty" doc:"the total number of cpu cores available to be created for this account"`
|
||||
CPULimit string `json:"cpulimit,omitempty" doc:"the total number of cpu cores the account can own"`
|
||||
CPUTotal int64 `json:"cputotal,omitempty" doc:"the total number of cpu cores owned by account"`
|
||||
DefaultZoneID *UUID `json:"defaultzoneid,omitempty" doc:"the default zone of the account"`
|
||||
Domain string `json:"domain,omitempty" doc:"name of the Domain the account belongs too"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"id of the Domain the account belongs too"`
|
||||
EipLimit string `json:"eiplimit,omitempty" doc:"the total number of public elastic ip addresses this account can acquire"`
|
||||
Groups []string `json:"groups,omitempty" doc:"the list of acl groups that account belongs to"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the id of the account"`
|
||||
|
@ -75,87 +55,26 @@ type Account struct {
|
|||
func (a Account) ListRequest() (ListCommand, error) {
|
||||
return &ListAccounts{
|
||||
ID: a.ID,
|
||||
DomainID: a.DomainID,
|
||||
AccountType: a.AccountType,
|
||||
State: a.State,
|
||||
}, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListAccounts
|
||||
|
||||
// ListAccounts represents a query to display the accounts
|
||||
type ListAccounts struct {
|
||||
AccountType AccountType `json:"accounttype,omitempty" doc:"list accounts by account type. Valid account types are 1 (admin), 2 (domain-admin), and 0 (user)."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ID *UUID `json:"id,omitempty" doc:"list account by account ID"`
|
||||
ID *UUID `json:"id,omitempty" doc:"List account by account ID"`
|
||||
IsCleanUpRequired *bool `json:"iscleanuprequired,omitempty" doc:"list accounts by cleanuprequired attribute (values are true or false)"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Name string `json:"name,omitempty" doc:"list account by account name"`
|
||||
Name string `json:"name,omitempty" doc:"List account by account name"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
State string `json:"state,omitempty" doc:"list accounts by state. Valid states are enabled, disabled, and locked."`
|
||||
State string `json:"state,omitempty" doc:"List accounts by state. Valid states are enabled, disabled, and locked."`
|
||||
_ bool `name:"listAccounts" description:"Lists accounts and provides detailed account information for listed accounts"`
|
||||
}
|
||||
|
||||
func (ListAccounts) response() interface{} {
|
||||
return new(ListAccountsResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (ls *ListAccounts) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListAccounts) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListAccounts) each(resp interface{}, callback IterateItemFunc) {
|
||||
vms, ok := resp.(*ListAccountsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type. ListAccountsResponse expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range vms.Account {
|
||||
if !callback(&vms.Account[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ListAccountsResponse represents a list of accounts
|
||||
type ListAccountsResponse struct {
|
||||
Count int `json:"count"`
|
||||
Account []Account `json:"account"`
|
||||
}
|
||||
|
||||
// EnableAccount represents the activation of an account
|
||||
type EnableAccount struct {
|
||||
Account string `json:"account,omitempty" doc:"Enables specified account."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"Enables specified account in this domain."`
|
||||
ID *UUID `json:"id,omitempty" doc:"Account id"`
|
||||
_ bool `name:"enableAccount" description:"Enables an account"`
|
||||
}
|
||||
|
||||
func (EnableAccount) response() interface{} {
|
||||
return new(Account)
|
||||
}
|
||||
|
||||
// DisableAccount (Async) represents the deactivation of an account
|
||||
type DisableAccount struct {
|
||||
Lock *bool `json:"lock" doc:"If true, only lock the account; else disable the account"`
|
||||
Account string `json:"account,omitempty" doc:"Disables specified account."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"Disables specified account in this domain."`
|
||||
ID *UUID `json:"id,omitempty" doc:"Account id"`
|
||||
_ bool `name:"disableAccount" description:"Disables an account"`
|
||||
}
|
||||
|
||||
func (DisableAccount) response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (DisableAccount) asyncResponse() interface{} {
|
||||
return new(Account)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/accounts_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/accounts_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListAccounts) Response() interface{} {
|
||||
return new(ListAccountsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListAccounts) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListAccounts) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListAccounts) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListAccounts) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListAccountsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListAccountsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.Account {
|
||||
if !callback(&items.Account[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
16
vendor/github.com/exoscale/egoscale/accounttype_string.go
generated
vendored
16
vendor/github.com/exoscale/egoscale/accounttype_string.go
generated
vendored
|
@ -1,16 +0,0 @@
|
|||
// Code generated by "stringer -type AccountType"; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "strconv"
|
||||
|
||||
const _AccountType_name = "UserAccountAdminAccountDomainAdminAccount"
|
||||
|
||||
var _AccountType_index = [...]uint8{0, 11, 23, 41}
|
||||
|
||||
func (i AccountType) String() string {
|
||||
if i < 0 || i >= AccountType(len(_AccountType_index)-1) {
|
||||
return "AccountType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _AccountType_name[_AccountType_index[i]:_AccountType_index[i+1]]
|
||||
}
|
69
vendor/github.com/exoscale/egoscale/addresses.go
generated
vendored
69
vendor/github.com/exoscale/egoscale/addresses.go
generated
vendored
|
@ -8,14 +8,10 @@ import (
|
|||
|
||||
// IPAddress represents an IP Address
|
||||
type IPAddress struct {
|
||||
Account string `json:"account,omitempty" doc:"the account the public IP address is associated with"`
|
||||
Allocated string `json:"allocated,omitempty" doc:"date the public IP address was acquired"`
|
||||
Associated string `json:"associated,omitempty" doc:"date the public IP address was associated"`
|
||||
AssociatedNetworkID *UUID `json:"associatednetworkid,omitempty" doc:"the ID of the Network associated with the IP address"`
|
||||
AssociatedNetworkName string `json:"associatednetworkname,omitempty" doc:"the name of the Network associated with the IP address"`
|
||||
Domain string `json:"domain,omitempty" doc:"the domain the public IP address is associated with"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain ID the public IP address is associated with"`
|
||||
ForDisplay bool `json:"fordisplay,omitempty" doc:"is public ip for display to the regular user"`
|
||||
ForVirtualNetwork bool `json:"forvirtualnetwork,omitempty" doc:"the virtual network for the IP address"`
|
||||
ID *UUID `json:"id,omitempty" doc:"public IP address id"`
|
||||
IPAddress net.IP `json:"ipaddress,omitempty" doc:"public IP address"`
|
||||
|
@ -48,9 +44,7 @@ func (IPAddress) ResourceType() string {
|
|||
// ListRequest builds the ListAdresses request
|
||||
func (ipaddress IPAddress) ListRequest() (ListCommand, error) {
|
||||
req := &ListPublicIPAddresses{
|
||||
Account: ipaddress.Account,
|
||||
AssociatedNetworkID: ipaddress.AssociatedNetworkID,
|
||||
DomainID: ipaddress.DomainID,
|
||||
ID: ipaddress.ID,
|
||||
IPAddress: ipaddress.IPAddress,
|
||||
PhysicalNetworkID: ipaddress.PhysicalNetworkID,
|
||||
|
@ -63,9 +57,6 @@ func (ipaddress IPAddress) ListRequest() (ListCommand, error) {
|
|||
if ipaddress.IsSourceNat {
|
||||
req.IsSourceNat = &ipaddress.IsSourceNat
|
||||
}
|
||||
if ipaddress.ForDisplay {
|
||||
req.ForDisplay = &ipaddress.ForDisplay
|
||||
}
|
||||
if ipaddress.ForVirtualNetwork {
|
||||
req.ForVirtualNetwork = &ipaddress.ForVirtualNetwork
|
||||
}
|
||||
|
@ -86,21 +77,19 @@ func (ipaddress IPAddress) Delete(ctx context.Context, client *Client) error {
|
|||
|
||||
// AssociateIPAddress (Async) represents the IP creation
|
||||
type AssociateIPAddress struct {
|
||||
Account string `json:"account,omitempty" doc:"the account to associate with this IP address"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the ID of the domain to associate with this IP address"`
|
||||
ForDisplay *bool `json:"fordisplay,omitempty" doc:"an optional field, whether to the display the ip to the end user or not"`
|
||||
IsPortable *bool `json:"isportable,omitempty" doc:"should be set to true if public IP is required to be transferable across zones, if not specified defaults to false"`
|
||||
NetworkdID *UUID `json:"networkid,omitempty" doc:"The network this ip address should be associated to."`
|
||||
RegionID int `json:"regionid,omitempty" doc:"region ID from where portable ip is to be associated."`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"the ID of the availability zone you want to acquire an public IP address from"`
|
||||
_ bool `name:"associateIpAddress" description:"Acquires and associates a public IP to an account."`
|
||||
}
|
||||
|
||||
func (AssociateIPAddress) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (AssociateIPAddress) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (AssociateIPAddress) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (AssociateIPAddress) AsyncResponse() interface{} {
|
||||
return new(IPAddress)
|
||||
}
|
||||
|
||||
|
@ -110,47 +99,47 @@ type DisassociateIPAddress struct {
|
|||
_ bool `name:"disassociateIpAddress" description:"Disassociates an ip address from the account."`
|
||||
}
|
||||
|
||||
func (DisassociateIPAddress) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (DisassociateIPAddress) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (DisassociateIPAddress) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (DisassociateIPAddress) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// UpdateIPAddress (Async) represents the IP modification
|
||||
type UpdateIPAddress struct {
|
||||
ID *UUID `json:"id" doc:"the id of the public ip address to update"`
|
||||
CustomID *UUID `json:"customid,omitempty" doc:"an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only"`
|
||||
ForDisplay *bool `json:"fordisplay,omitempty" doc:"an optional field, whether to the display the ip to the end user or not"`
|
||||
_ bool `name:"updateIpAddress" description:"Updates an ip address"`
|
||||
}
|
||||
|
||||
func (UpdateIPAddress) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (UpdateIPAddress) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (UpdateIPAddress) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (UpdateIPAddress) AsyncResponse() interface{} {
|
||||
return new(IPAddress)
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListPublicIPAddresses
|
||||
|
||||
// ListPublicIPAddresses represents a search for public IP addresses
|
||||
type ListPublicIPAddresses struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
AllocatedOnly *bool `json:"allocatedonly,omitempty" doc:"limits search results to allocated public IP addresses"`
|
||||
AssociatedNetworkID *UUID `json:"associatednetworkid,omitempty" doc:"lists all public IP addresses associated to the network specified"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ForDisplay *bool `json:"fordisplay,omitempty" doc:"list resources by display flag; only ROOT admin is eligible to pass this parameter"`
|
||||
ForLoadBalancing *bool `json:"forloadbalancing,omitempty" doc:"list only ips used for load balancing"`
|
||||
ForVirtualNetwork *bool `json:"forvirtualnetwork,omitempty" doc:"the virtual network for the IP address"`
|
||||
ID *UUID `json:"id,omitempty" doc:"lists ip address by id"`
|
||||
IPAddress net.IP `json:"ipaddress,omitempty" doc:"lists the specified IP address"`
|
||||
IsElastic *bool `json:"iselastic,omitempty" doc:"list only elastic ip addresses"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
IsSourceNat *bool `json:"issourcenat,omitempty" doc:"list only source nat ip addresses"`
|
||||
IsStaticNat *bool `json:"isstaticnat,omitempty" doc:"list only static nat ip addresses"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
PhysicalNetworkID *UUID `json:"physicalnetworkid,omitempty" doc:"lists all public IP addresses by physical network id"`
|
||||
|
@ -165,31 +154,3 @@ type ListPublicIPAddressesResponse struct {
|
|||
Count int `json:"count"`
|
||||
PublicIPAddress []IPAddress `json:"publicipaddress"`
|
||||
}
|
||||
|
||||
func (ListPublicIPAddresses) response() interface{} {
|
||||
return new(ListPublicIPAddressesResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (ls *ListPublicIPAddresses) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListPublicIPAddresses) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListPublicIPAddresses) each(resp interface{}, callback IterateItemFunc) {
|
||||
ips, ok := resp.(*ListPublicIPAddressesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type. ListPublicIPAddressesResponse expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range ips.PublicIPAddress {
|
||||
if !callback(&ips.PublicIPAddress[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
88
vendor/github.com/exoscale/egoscale/affinity_groups.go
generated
vendored
88
vendor/github.com/exoscale/egoscale/affinity_groups.go
generated
vendored
|
@ -13,8 +13,6 @@ import (
|
|||
type AffinityGroup struct {
|
||||
Account string `json:"account,omitempty" doc:"the account owning the affinity group"`
|
||||
Description string `json:"description,omitempty" doc:"the description of the affinity group"`
|
||||
Domain string `json:"domain,omitempty" doc:"the domain name of the affinity group"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain ID of the affinity group"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the ID of the affinity group"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the affinity group"`
|
||||
Type string `json:"type,omitempty" doc:"the type of the affinity group"`
|
||||
|
@ -35,10 +33,7 @@ func (ag AffinityGroup) Delete(ctx context.Context, client *Client) error {
|
|||
return fmt.Errorf("an Affinity Group may only be deleted using ID or Name")
|
||||
}
|
||||
|
||||
req := &DeleteAffinityGroup{
|
||||
Account: ag.Account,
|
||||
DomainID: ag.DomainID,
|
||||
}
|
||||
req := &DeleteAffinityGroup{}
|
||||
|
||||
if ag.ID != nil {
|
||||
req.ID = ag.ID
|
||||
|
@ -56,19 +51,27 @@ type AffinityGroupType struct {
|
|||
|
||||
// CreateAffinityGroup (Async) represents a new (anti-)affinity group
|
||||
type CreateAffinityGroup struct {
|
||||
Account string `json:"account,omitempty" doc:"an account for the affinity group. Must be used with domainId."`
|
||||
Description string `json:"description,omitempty" doc:"optional description of the affinity group"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"domainId of the account owning the affinity group"`
|
||||
Name string `json:"name" doc:"name of the affinity group"`
|
||||
Description string `json:"description,omitempty" doc:"Optional description of the affinity group"`
|
||||
Name string `json:"name,omitempty" doc:"Name of the affinity group"`
|
||||
Type string `json:"type" doc:"Type of the affinity group from the available affinity/anti-affinity group types"`
|
||||
_ bool `name:"createAffinityGroup" description:"Creates an affinity/anti-affinity group"`
|
||||
}
|
||||
|
||||
func (CreateAffinityGroup) response() interface{} {
|
||||
func (req CreateAffinityGroup) onBeforeSend(params url.Values) error {
|
||||
// Name must be set, but can be empty
|
||||
if req.Name == "" {
|
||||
params.Set("name", "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (CreateAffinityGroup) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (CreateAffinityGroup) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (CreateAffinityGroup) AsyncResponse() interface{} {
|
||||
return new(AffinityGroup)
|
||||
}
|
||||
|
||||
|
@ -88,75 +91,47 @@ func (req UpdateVMAffinityGroup) onBeforeSend(params url.Values) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (UpdateVMAffinityGroup) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (UpdateVMAffinityGroup) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (UpdateVMAffinityGroup) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (UpdateVMAffinityGroup) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
// DeleteAffinityGroup (Async) represents an (anti-)affinity group to be deleted
|
||||
type DeleteAffinityGroup struct {
|
||||
Account string `json:"account,omitempty" doc:"the account of the affinity group. Must be specified with domain ID"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain ID of account owning the affinity group"`
|
||||
ID *UUID `json:"id,omitempty" doc:"The ID of the affinity group. Mutually exclusive with name parameter"`
|
||||
Name string `json:"name,omitempty" doc:"The name of the affinity group. Mutually exclusive with ID parameter"`
|
||||
_ bool `name:"deleteAffinityGroup" description:"Deletes affinity group"`
|
||||
}
|
||||
|
||||
func (DeleteAffinityGroup) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (DeleteAffinityGroup) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (DeleteAffinityGroup) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (DeleteAffinityGroup) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListAffinityGroups
|
||||
|
||||
// ListAffinityGroups represents an (anti-)affinity groups search
|
||||
type ListAffinityGroups struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ID *UUID `json:"id,omitempty" doc:"list the affinity group by the ID provided"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
ID *UUID `json:"id,omitempty" doc:"List the affinity group by the ID provided"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Name string `json:"name,omitempty" doc:"lists affinity groups by name"`
|
||||
Name string `json:"name,omitempty" doc:"Lists affinity groups by name"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
Type string `json:"type,omitempty" doc:"lists affinity groups by type"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"lists affinity groups by virtual machine ID"`
|
||||
Type string `json:"type,omitempty" doc:"Lists affinity groups by type"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"Lists affinity groups by virtual machine ID"`
|
||||
_ bool `name:"listAffinityGroups" description:"Lists affinity groups"`
|
||||
}
|
||||
|
||||
func (ListAffinityGroups) response() interface{} {
|
||||
return new(ListAffinityGroupsResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (ls *ListAffinityGroups) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListAffinityGroups) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListAffinityGroups) each(resp interface{}, callback IterateItemFunc) {
|
||||
vms, ok := resp.(*ListAffinityGroupsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type. ListAffinityGroupsResponse expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range vms.AffinityGroup {
|
||||
if !callback(&vms.AffinityGroup[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ListAffinityGroupsResponse represents a list of (anti-)affinity groups
|
||||
type ListAffinityGroupsResponse struct {
|
||||
Count int `json:"count"`
|
||||
|
@ -171,7 +146,8 @@ type ListAffinityGroupTypes struct {
|
|||
_ bool `name:"listAffinityGroupTypes" description:"Lists affinity group types available"`
|
||||
}
|
||||
|
||||
func (ListAffinityGroupTypes) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListAffinityGroupTypes) Response() interface{} {
|
||||
return new(ListAffinityGroupTypesResponse)
|
||||
}
|
||||
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/affinitygroups_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/affinitygroups_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListAffinityGroups) Response() interface{} {
|
||||
return new(ListAffinityGroupsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListAffinityGroups) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListAffinityGroups) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListAffinityGroups) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListAffinityGroups) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListAffinityGroupsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListAffinityGroupsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.AffinityGroup {
|
||||
if !callback(&items.AffinityGroup[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
5
vendor/github.com/exoscale/egoscale/apis.go
generated
vendored
5
vendor/github.com/exoscale/egoscale/apis.go
generated
vendored
|
@ -3,7 +3,7 @@ package egoscale
|
|||
// API represents an API service
|
||||
type API struct {
|
||||
Description string `json:"description,omitempty" doc:"description of the api"`
|
||||
IsAsync bool `json:"isasync,omitempty" doc:"true if api is asynchronous"`
|
||||
IsAsync bool `json:"isasync" doc:"true if api is asynchronous"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the api command"`
|
||||
Related string `json:"related,omitempty" doc:"comma separated related apis"`
|
||||
Since string `json:"since,omitempty" doc:"version of CloudStack the api was introduced in"`
|
||||
|
@ -42,6 +42,7 @@ type ListAPIsResponse struct {
|
|||
API []API `json:"api"`
|
||||
}
|
||||
|
||||
func (*ListAPIs) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (*ListAPIs) Response() interface{} {
|
||||
return new(ListAPIsResponse)
|
||||
}
|
||||
|
|
27
vendor/github.com/exoscale/egoscale/async_jobs.go
generated
vendored
27
vendor/github.com/exoscale/egoscale/async_jobs.go
generated
vendored
|
@ -10,7 +10,7 @@ type AsyncJobResult struct {
|
|||
AccountID *UUID `json:"accountid,omitempty" doc:"the account that executed the async command"`
|
||||
Cmd string `json:"cmd,omitempty" doc:"the async command executed"`
|
||||
Created string `json:"created,omitempty" doc:"the created date of the job"`
|
||||
JobID *UUID `json:"jobid,omitempty" doc:"extra field for the initial async call"`
|
||||
JobID *UUID `json:"jobid" doc:"extra field for the initial async call"`
|
||||
JobInstanceID *UUID `json:"jobinstanceid,omitempty" doc:"the unique ID of the instance/entity object related to the job"`
|
||||
JobInstanceType string `json:"jobinstancetype,omitempty" doc:"the instance/entity object related to the job"`
|
||||
JobProcStatus int `json:"jobprocstatus,omitempty" doc:"the progress information of the PENDING job"`
|
||||
|
@ -21,6 +21,16 @@ type AsyncJobResult struct {
|
|||
UserID *UUID `json:"userid,omitempty" doc:"the user that executed the async command"`
|
||||
}
|
||||
|
||||
// ListRequest buils the (empty) ListAsyncJobs request
|
||||
func (a AsyncJobResult) ListRequest() (ListCommand, error) {
|
||||
req := &ListAsyncJobs{
|
||||
StartDate: a.Created,
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// Error builds an error message from the result
|
||||
func (a AsyncJobResult) Error() error {
|
||||
r := new(ErrorResponse)
|
||||
if e := json.Unmarshal(*a.JobResult, r); e != nil {
|
||||
|
@ -35,17 +45,16 @@ type QueryAsyncJobResult struct {
|
|||
_ bool `name:"queryAsyncJobResult" description:"Retrieves the current status of asynchronous job."`
|
||||
}
|
||||
|
||||
func (QueryAsyncJobResult) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (QueryAsyncJobResult) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListAsyncJobs
|
||||
|
||||
// ListAsyncJobs list the asynchronous jobs
|
||||
type ListAsyncJobs struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
StartDate string `json:"startdate,omitempty" doc:"the start date of the async job"`
|
||||
|
@ -55,11 +64,7 @@ type ListAsyncJobs struct {
|
|||
// ListAsyncJobsResponse represents a list of job results
|
||||
type ListAsyncJobsResponse struct {
|
||||
Count int `json:"count"`
|
||||
AsyncJobs []AsyncJobResult `json:"asyncjobs"`
|
||||
}
|
||||
|
||||
func (ListAsyncJobs) response() interface{} {
|
||||
return new(ListAsyncJobsResponse)
|
||||
AsyncJob []AsyncJobResult `json:"asyncjobs"`
|
||||
}
|
||||
|
||||
// Result unmarshals the result of an AsyncJobResult into the given interface
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/asyncjobs_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/asyncjobs_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListAsyncJobs) Response() interface{} {
|
||||
return new(ListAsyncJobsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListAsyncJobs) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListAsyncJobs) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListAsyncJobs) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListAsyncJobs) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListAsyncJobsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListAsyncJobsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.AsyncJob {
|
||||
if !callback(&items.AsyncJob[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
105
vendor/github.com/exoscale/egoscale/client.go
generated
vendored
105
vendor/github.com/exoscale/egoscale/client.go
generated
vendored
|
@ -13,11 +13,11 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Taggable represents a resource which can have tags attached
|
||||
// Taggable represents a resource to which tags can be attached
|
||||
//
|
||||
// This is a helper to fill the resourcetype of a CreateTags call
|
||||
type Taggable interface {
|
||||
// CloudStack resource type of the Taggable type
|
||||
// ResourceType is the name of the Taggable type
|
||||
ResourceType() string
|
||||
}
|
||||
|
||||
|
@ -33,16 +33,11 @@ type Listable interface {
|
|||
ListRequest() (ListCommand, error)
|
||||
}
|
||||
|
||||
// Gettable represents an Interface that can be "Get" by the client
|
||||
type Gettable interface {
|
||||
Listable
|
||||
}
|
||||
|
||||
// Client represents the CloudStack API client
|
||||
// Client represents the API client
|
||||
type Client struct {
|
||||
// HTTPClient holds the HTTP client
|
||||
HTTPClient *http.Client
|
||||
// Endpoints is CloudStack API
|
||||
// Endpoint is the HTTP URL
|
||||
Endpoint string
|
||||
// APIKey is the API identifier
|
||||
APIKey string
|
||||
|
@ -52,13 +47,15 @@ type Client struct {
|
|||
PageSize int
|
||||
// Timeout represents the default timeout for the async requests
|
||||
Timeout time.Duration
|
||||
// Expiration representation how long a signed payload may be used
|
||||
Expiration time.Duration
|
||||
// RetryStrategy represents the waiting strategy for polling the async requests
|
||||
RetryStrategy RetryStrategyFunc
|
||||
// Logger contains any log, plug your own
|
||||
Logger *log.Logger
|
||||
}
|
||||
|
||||
// RetryStrategyFunc represents a how much time to wait between two calls to CloudStack
|
||||
// RetryStrategyFunc represents a how much time to wait between two calls to the API
|
||||
type RetryStrategyFunc func(int64) time.Duration
|
||||
|
||||
// IterateItemFunc represents the callback to iterate a list of results, if false stops
|
||||
|
@ -67,11 +64,12 @@ type IterateItemFunc func(interface{}, error) bool
|
|||
// WaitAsyncJobResultFunc represents the callback to wait a results of an async request, if false stops
|
||||
type WaitAsyncJobResultFunc func(*AsyncJobResult, error) bool
|
||||
|
||||
// NewClient creates a CloudStack API client with default timeout (60)
|
||||
// NewClient creates an API client with default timeout (60)
|
||||
//
|
||||
// Timeout is set to both the HTTP client and the client itself.
|
||||
func NewClient(endpoint, apiKey, apiSecret string) *Client {
|
||||
timeout := 60 * time.Second
|
||||
expiration := 10 * time.Minute
|
||||
|
||||
httpClient := &http.Client{
|
||||
Transport: http.DefaultTransport,
|
||||
|
@ -84,6 +82,7 @@ func NewClient(endpoint, apiKey, apiSecret string) *Client {
|
|||
apiSecret: apiSecret,
|
||||
PageSize: 50,
|
||||
Timeout: timeout,
|
||||
Expiration: expiration,
|
||||
RetryStrategy: MonotonicRetryStrategyFunc(2),
|
||||
Logger: log.New(ioutil.Discard, "", 0),
|
||||
}
|
||||
|
@ -97,45 +96,52 @@ func NewClient(endpoint, apiKey, apiSecret string) *Client {
|
|||
}
|
||||
|
||||
// Get populates the given resource or fails
|
||||
func (client *Client) Get(g Gettable) error {
|
||||
func (client *Client) Get(ls Listable) (interface{}, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), client.Timeout)
|
||||
defer cancel()
|
||||
|
||||
return client.GetWithContext(ctx, g)
|
||||
return client.GetWithContext(ctx, ls)
|
||||
}
|
||||
|
||||
// GetWithContext populates the given resource or fails
|
||||
func (client *Client) GetWithContext(ctx context.Context, g Gettable) error {
|
||||
gs, err := client.ListWithContext(ctx, g)
|
||||
func (client *Client) GetWithContext(ctx context.Context, ls Listable) (interface{}, error) {
|
||||
gs, err := client.ListWithContext(ctx, ls)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
count := len(gs)
|
||||
if count != 1 {
|
||||
req, err := g.ListRequest()
|
||||
req, err := ls.ListRequest()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
params, err := client.Payload(req)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// removing sensitive/useless informations
|
||||
params.Del("expires")
|
||||
params.Del("response")
|
||||
params.Del("signature")
|
||||
params.Del("signatureversion")
|
||||
|
||||
// formatting the query string nicely
|
||||
payload := params.Encode()
|
||||
payload = strings.Replace(payload, "&", ", ", -1)
|
||||
|
||||
if count == 0 {
|
||||
return &ErrorResponse{
|
||||
return nil, &ErrorResponse{
|
||||
CSErrorCode: ServerAPIException,
|
||||
ErrorCode: ParamError,
|
||||
ErrorText: fmt.Sprintf("not found, query: %s", payload),
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("more than one element found: %s", payload)
|
||||
return nil, fmt.Errorf("more than one element found: %s", payload)
|
||||
}
|
||||
|
||||
return Copy(g, gs[0])
|
||||
return gs[0], nil
|
||||
}
|
||||
|
||||
// Delete removes the given resource of fails
|
||||
|
@ -160,18 +166,25 @@ func (client *Client) List(g Listable) ([]interface{}, error) {
|
|||
}
|
||||
|
||||
// ListWithContext lists the given resources (and paginate till the end)
|
||||
func (client *Client) ListWithContext(ctx context.Context, g Listable) ([]interface{}, error) {
|
||||
s := make([]interface{}, 0)
|
||||
func (client *Client) ListWithContext(ctx context.Context, g Listable) (s []interface{}, err error) {
|
||||
s = make([]interface{}, 0)
|
||||
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
if g == nil || reflect.ValueOf(g).IsNil() {
|
||||
return s, fmt.Errorf("g Listable shouldn't be nil, got %#v", g)
|
||||
err = fmt.Errorf("g Listable shouldn't be nil, got %#v", g)
|
||||
return
|
||||
}
|
||||
|
||||
req, err := g.ListRequest()
|
||||
if err != nil {
|
||||
return s, err
|
||||
panic(e)
|
||||
}
|
||||
}()
|
||||
|
||||
req, e := g.ListRequest()
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
client.PaginateWithContext(ctx, req, func(item interface{}, e error) bool {
|
||||
if item != nil {
|
||||
s = append(s, item)
|
||||
|
@ -181,7 +194,7 @@ func (client *Client) ListWithContext(ctx context.Context, g Listable) ([]interf
|
|||
return false
|
||||
})
|
||||
|
||||
return s, err
|
||||
return
|
||||
}
|
||||
|
||||
// AsyncListWithContext lists the given resources (and paginate till the end)
|
||||
|
@ -227,7 +240,6 @@ func (client *Client) AsyncListWithContext(ctx context.Context, g Listable) (<-c
|
|||
errChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
client.PaginateWithContext(ctx, req, func(item interface{}, e error) bool {
|
||||
if item != nil {
|
||||
outChan <- item
|
||||
|
@ -242,15 +254,21 @@ func (client *Client) AsyncListWithContext(ctx context.Context, g Listable) (<-c
|
|||
}
|
||||
|
||||
// Paginate runs the ListCommand and paginates
|
||||
func (client *Client) Paginate(req ListCommand, callback IterateItemFunc) {
|
||||
func (client *Client) Paginate(g Listable, callback IterateItemFunc) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), client.Timeout)
|
||||
defer cancel()
|
||||
|
||||
client.PaginateWithContext(ctx, req, callback)
|
||||
client.PaginateWithContext(ctx, g, callback)
|
||||
}
|
||||
|
||||
// PaginateWithContext runs the ListCommand as long as the ctx is valid
|
||||
func (client *Client) PaginateWithContext(ctx context.Context, req ListCommand, callback IterateItemFunc) {
|
||||
func (client *Client) PaginateWithContext(ctx context.Context, g Listable, callback IterateItemFunc) {
|
||||
req, err := g.ListRequest()
|
||||
if err != nil {
|
||||
callback(nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
pageSize := client.PageSize
|
||||
|
||||
page := 1
|
||||
|
@ -260,13 +278,18 @@ func (client *Client) PaginateWithContext(ctx context.Context, req ListCommand,
|
|||
req.SetPageSize(pageSize)
|
||||
resp, err := client.RequestWithContext(ctx, req)
|
||||
if err != nil {
|
||||
// in case of 431, the response is knowingly empty
|
||||
if errResponse, ok := err.(*ErrorResponse); ok && page == 1 && errResponse.ErrorCode == ParamError {
|
||||
break
|
||||
}
|
||||
|
||||
callback(nil, err)
|
||||
break
|
||||
}
|
||||
|
||||
size := 0
|
||||
didErr := false
|
||||
req.each(resp, func(element interface{}, err error) bool {
|
||||
req.Each(resp, func(element interface{}, err error) bool {
|
||||
// If the context was cancelled, kill it in flight
|
||||
if e := ctx.Err(); e != nil {
|
||||
element = nil
|
||||
|
@ -290,10 +313,12 @@ func (client *Client) PaginateWithContext(ctx context.Context, req ListCommand,
|
|||
}
|
||||
}
|
||||
|
||||
// APIName returns the CloudStack name of the given command
|
||||
// APIName returns the name of the given command
|
||||
func (client *Client) APIName(command Command) string {
|
||||
// This is due to a limitation of Go<=1.7
|
||||
if _, ok := command.(*AuthorizeSecurityGroupEgress); ok {
|
||||
_, ok := command.(*AuthorizeSecurityGroupEgress)
|
||||
_, okPtr := command.(AuthorizeSecurityGroupEgress)
|
||||
if ok || okPtr {
|
||||
return "authorizeSecurityGroupEgress"
|
||||
}
|
||||
|
||||
|
@ -304,7 +329,7 @@ func (client *Client) APIName(command Command) string {
|
|||
return info.Name
|
||||
}
|
||||
|
||||
// APIDescription returns the description of the given CloudStack command
|
||||
// APIDescription returns the description of the given command
|
||||
func (client *Client) APIDescription(command Command) string {
|
||||
info, err := info(command)
|
||||
if err != nil {
|
||||
|
@ -315,11 +340,11 @@ func (client *Client) APIDescription(command Command) string {
|
|||
|
||||
// Response returns the response structure of the given command
|
||||
func (client *Client) Response(command Command) interface{} {
|
||||
switch command.(type) {
|
||||
switch c := command.(type) {
|
||||
case AsyncCommand:
|
||||
return (command.(AsyncCommand)).asyncResponse()
|
||||
return c.AsyncResponse()
|
||||
default:
|
||||
return command.response()
|
||||
return command.Response()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
37
vendor/github.com/exoscale/egoscale/copier.go
generated
vendored
37
vendor/github.com/exoscale/egoscale/copier.go
generated
vendored
|
@ -1,37 +0,0 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Copy copies the value from from into to. The type of "from" must be convertible into the type of "to".
|
||||
func Copy(to, from interface{}) error {
|
||||
tt := reflect.TypeOf(to)
|
||||
tv := reflect.ValueOf(to)
|
||||
|
||||
ft := reflect.TypeOf(from)
|
||||
fv := reflect.ValueOf(from)
|
||||
|
||||
if tt.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("must copy to a pointer, got %q", tt.Name())
|
||||
}
|
||||
|
||||
tt = tt.Elem()
|
||||
tv = tv.Elem()
|
||||
|
||||
for {
|
||||
if ft.ConvertibleTo(tt) {
|
||||
break
|
||||
}
|
||||
if ft.Kind() == reflect.Ptr {
|
||||
ft = ft.Elem()
|
||||
fv = fv.Elem()
|
||||
} else {
|
||||
return fmt.Errorf("cannot convert %q into %q", tt.Name(), ft.Name())
|
||||
}
|
||||
}
|
||||
|
||||
tv.Set(fv.Convert(tt))
|
||||
return nil
|
||||
}
|
45
vendor/github.com/exoscale/egoscale/dns.go
generated
vendored
45
vendor/github.com/exoscale/egoscale/dns.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
@ -128,7 +129,7 @@ func (req *DNSErrorResponse) Error() string {
|
|||
}
|
||||
|
||||
// CreateDomain creates a DNS domain
|
||||
func (client *Client) CreateDomain(name string) (*DNSDomain, error) {
|
||||
func (client *Client) CreateDomain(ctx context.Context, name string) (*DNSDomain, error) {
|
||||
m, err := json.Marshal(DNSDomainResponse{
|
||||
Domain: &DNSDomain{
|
||||
Name: name,
|
||||
|
@ -138,7 +139,7 @@ func (client *Client) CreateDomain(name string) (*DNSDomain, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := client.dnsRequest("/v1/domains", nil, string(m), "POST")
|
||||
resp, err := client.dnsRequest(ctx, "/v1/domains", nil, string(m), "POST")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -152,8 +153,8 @@ func (client *Client) CreateDomain(name string) (*DNSDomain, error) {
|
|||
}
|
||||
|
||||
// GetDomain gets a DNS domain
|
||||
func (client *Client) GetDomain(name string) (*DNSDomain, error) {
|
||||
resp, err := client.dnsRequest("/v1/domains/"+name, nil, "", "GET")
|
||||
func (client *Client) GetDomain(ctx context.Context, name string) (*DNSDomain, error) {
|
||||
resp, err := client.dnsRequest(ctx, "/v1/domains/"+name, nil, "", "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -167,8 +168,8 @@ func (client *Client) GetDomain(name string) (*DNSDomain, error) {
|
|||
}
|
||||
|
||||
// GetDomains gets DNS domains
|
||||
func (client *Client) GetDomains() ([]DNSDomain, error) {
|
||||
resp, err := client.dnsRequest("/v1/domains", nil, "", "GET")
|
||||
func (client *Client) GetDomains(ctx context.Context) ([]DNSDomain, error) {
|
||||
resp, err := client.dnsRequest(ctx, "/v1/domains", nil, "", "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -186,15 +187,15 @@ func (client *Client) GetDomains() ([]DNSDomain, error) {
|
|||
}
|
||||
|
||||
// DeleteDomain delets a DNS domain
|
||||
func (client *Client) DeleteDomain(name string) error {
|
||||
_, err := client.dnsRequest("/v1/domains/"+name, nil, "", "DELETE")
|
||||
func (client *Client) DeleteDomain(ctx context.Context, name string) error {
|
||||
_, err := client.dnsRequest(ctx, "/v1/domains/"+name, nil, "", "DELETE")
|
||||
return err
|
||||
}
|
||||
|
||||
// GetRecord returns a DNS record
|
||||
func (client *Client) GetRecord(domain string, recordID int64) (*DNSRecord, error) {
|
||||
func (client *Client) GetRecord(ctx context.Context, domain string, recordID int64) (*DNSRecord, error) {
|
||||
id := strconv.FormatInt(recordID, 10)
|
||||
resp, err := client.dnsRequest("/v1/domains/"+domain+"/records/"+id, nil, "", "GET")
|
||||
resp, err := client.dnsRequest(ctx, "/v1/domains/"+domain+"/records/"+id, nil, "", "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -208,8 +209,8 @@ func (client *Client) GetRecord(domain string, recordID int64) (*DNSRecord, erro
|
|||
}
|
||||
|
||||
// GetRecords returns the DNS records
|
||||
func (client *Client) GetRecords(domain string) ([]DNSRecord, error) {
|
||||
resp, err := client.dnsRequest("/v1/domains/"+domain+"/records", nil, "", "GET")
|
||||
func (client *Client) GetRecords(ctx context.Context, domain string) ([]DNSRecord, error) {
|
||||
resp, err := client.dnsRequest(ctx, "/v1/domains/"+domain+"/records", nil, "", "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -228,7 +229,7 @@ func (client *Client) GetRecords(domain string) ([]DNSRecord, error) {
|
|||
}
|
||||
|
||||
// GetRecordsWithFilters returns the DNS records (filters can be empty)
|
||||
func (client *Client) GetRecordsWithFilters(domain, name, recordType string) ([]DNSRecord, error) {
|
||||
func (client *Client) GetRecordsWithFilters(ctx context.Context, domain, name, recordType string) ([]DNSRecord, error) {
|
||||
|
||||
filters := url.Values{}
|
||||
if name != "" {
|
||||
|
@ -238,7 +239,7 @@ func (client *Client) GetRecordsWithFilters(domain, name, recordType string) ([]
|
|||
filters.Add("record_type", recordType)
|
||||
}
|
||||
|
||||
resp, err := client.dnsRequest("/v1/domains/"+domain+"/records", filters, "", "GET")
|
||||
resp, err := client.dnsRequest(ctx, "/v1/domains/"+domain+"/records", filters, "", "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -257,7 +258,7 @@ func (client *Client) GetRecordsWithFilters(domain, name, recordType string) ([]
|
|||
}
|
||||
|
||||
// CreateRecord creates a DNS record
|
||||
func (client *Client) CreateRecord(name string, rec DNSRecord) (*DNSRecord, error) {
|
||||
func (client *Client) CreateRecord(ctx context.Context, name string, rec DNSRecord) (*DNSRecord, error) {
|
||||
body, err := json.Marshal(DNSRecordResponse{
|
||||
Record: rec,
|
||||
})
|
||||
|
@ -265,7 +266,7 @@ func (client *Client) CreateRecord(name string, rec DNSRecord) (*DNSRecord, erro
|
|||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := client.dnsRequest("/v1/domains/"+name+"/records", nil, string(body), "POST")
|
||||
resp, err := client.dnsRequest(ctx, "/v1/domains/"+name+"/records", nil, string(body), "POST")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -279,7 +280,7 @@ func (client *Client) CreateRecord(name string, rec DNSRecord) (*DNSRecord, erro
|
|||
}
|
||||
|
||||
// UpdateRecord updates a DNS record
|
||||
func (client *Client) UpdateRecord(name string, rec UpdateDNSRecord) (*DNSRecord, error) {
|
||||
func (client *Client) UpdateRecord(ctx context.Context, name string, rec UpdateDNSRecord) (*DNSRecord, error) {
|
||||
body, err := json.Marshal(UpdateDNSRecordResponse{
|
||||
Record: rec,
|
||||
})
|
||||
|
@ -288,7 +289,7 @@ func (client *Client) UpdateRecord(name string, rec UpdateDNSRecord) (*DNSRecord
|
|||
}
|
||||
|
||||
id := strconv.FormatInt(rec.ID, 10)
|
||||
resp, err := client.dnsRequest("/v1/domains/"+name+"/records/"+id, nil, string(body), "PUT")
|
||||
resp, err := client.dnsRequest(ctx, "/v1/domains/"+name+"/records/"+id, nil, string(body), "PUT")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -302,14 +303,14 @@ func (client *Client) UpdateRecord(name string, rec UpdateDNSRecord) (*DNSRecord
|
|||
}
|
||||
|
||||
// DeleteRecord deletes a record
|
||||
func (client *Client) DeleteRecord(name string, recordID int64) error {
|
||||
func (client *Client) DeleteRecord(ctx context.Context, name string, recordID int64) error {
|
||||
id := strconv.FormatInt(recordID, 10)
|
||||
_, err := client.dnsRequest("/v1/domains/"+name+"/records/"+id, nil, "", "DELETE")
|
||||
_, err := client.dnsRequest(ctx, "/v1/domains/"+name+"/records/"+id, nil, "", "DELETE")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *Client) dnsRequest(uri string, urlValues url.Values, params, method string) (json.RawMessage, error) {
|
||||
func (client *Client) dnsRequest(ctx context.Context, uri string, urlValues url.Values, params, method string) (json.RawMessage, error) {
|
||||
rawURL := client.Endpoint + uri
|
||||
url, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
|
@ -338,7 +339,7 @@ func (client *Client) dnsRequest(uri string, urlValues url.Values, params, metho
|
|||
}
|
||||
req.Header = hdr
|
||||
|
||||
resp, err := client.HTTPClient.Do(req)
|
||||
resp, err := client.HTTPClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
49
vendor/github.com/exoscale/egoscale/doc.go
generated
vendored
49
vendor/github.com/exoscale/egoscale/doc.go
generated
vendored
|
@ -1,18 +1,18 @@
|
|||
/*
|
||||
|
||||
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.com/) infrastructure but should fit other CloudStack services.
|
||||
Package egoscale is a mapping for the Exoscale API (https://community.exoscale.com/api/compute/).
|
||||
|
||||
Requests and Responses
|
||||
|
||||
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 data at stake. E.g. DeployVirtualMachine gives a VirtualMachine, as a pointer as well to avoid big copies.
|
||||
|
||||
Then everything within the struct is not a pointer. Find below some examples of how egoscale may be used to interact with a CloudStack endpoint, especially Exoscale itself. If anything feels odd or unclear, please let us know: https://github.com/exoscale/egoscale/issues
|
||||
Then everything within the struct is not a pointer. Find below some examples of how egoscale may be used. If anything feels odd or unclear, please let us know: https://github.com/exoscale/egoscale/issues
|
||||
|
||||
req := &egoscale.DeployVirtualMachine{
|
||||
Size: 10,
|
||||
ServiceOfferingID: "...",
|
||||
TemplateID: "...",
|
||||
ZoneID: "...",
|
||||
ServiceOfferingID: egoscale.MustParseUUID("..."),
|
||||
TemplateID: egoscale.MustParseUUID("..."),
|
||||
ZoneID: egoscale.MastParseUUID("..."),
|
||||
}
|
||||
|
||||
fmt.Println("Deployment started")
|
||||
|
@ -28,9 +28,9 @@ This example deploys a virtual machine while controlling the job status as it go
|
|||
|
||||
req := &egoscale.DeployVirtualMachine{
|
||||
Size: 10,
|
||||
ServiceOfferingID: "...",
|
||||
TemplateID: "...",
|
||||
ZoneID: "...",
|
||||
ServiceOfferingID: egoscale.MustParseUUID("..."),
|
||||
TemplateID: egoscale.MustParseUUID("..."),
|
||||
ZoneID: egoscale.MustParseUUID("..."),
|
||||
}
|
||||
vm := &egoscale.VirtualMachine{}
|
||||
|
||||
|
@ -63,20 +63,20 @@ Debugging and traces
|
|||
|
||||
As this library is mostly an HTTP client, you can reuse all the existing tools around it.
|
||||
|
||||
cs := egoscale.NewClient("https://api.exoscale.ch/compute", "EXO...", "...")
|
||||
cs := egoscale.NewClient("https://api.exoscale.com/compute", "EXO...", "...")
|
||||
// sets a logger on stderr
|
||||
cs.Logger = log.Newos.Stderr, "prefix", log.LstdFlags)
|
||||
cs.Logger = log.New(os.Stderr, "prefix", log.LstdFlags)
|
||||
// activates the HTTP traces
|
||||
cs.TraceOn()
|
||||
|
||||
Nota bene: when running the tests or the egoscale library via another tool, e.g. the exo cli (or the cs cli), the environment variable EXOSCALE_TRACE=prefix does the above configuration for you. As a developer using egoscale as a library, you'll find it more convenient to plug your favorite io.Writer as it's Logger.
|
||||
Nota bene: when running the tests or the egoscale library via another tool, e.g. the exo cli, the environment variable EXOSCALE_TRACE=prefix does the above configuration for you. As a developer using egoscale as a library, you'll find it more convenient to plug your favorite io.Writer as it's a Logger.
|
||||
|
||||
|
||||
APIs
|
||||
|
||||
All the available APIs on the server and provided by the API Discovery plugin
|
||||
All the available APIs on the server and provided by the API Discovery plugin.
|
||||
|
||||
cs := egoscale.NewClient("https://api.exoscale.ch/compute", "EXO...", "...")
|
||||
cs := egoscale.NewClient("https://api.exoscale.com/compute", "EXO...", "...")
|
||||
|
||||
resp, err := cs.Request(&egoscale.ListAPIs{})
|
||||
if err != nil {
|
||||
|
@ -96,14 +96,17 @@ Security Groups provide a way to isolate traffic to VMs. Rules are added via the
|
|||
|
||||
resp, err := cs.Request(&egoscale.CreateSecurityGroup{
|
||||
Name: "Load balancer",
|
||||
Description: "Opens HTTP/HTTPS ports from the outside world",
|
||||
Description: "Open HTTP/HTTPS ports from the outside world",
|
||||
})
|
||||
securityGroup := resp.(*egoscale.SecurityGroup)
|
||||
|
||||
resp, err = cs.Request(&egoscale.AuthorizeSecurityGroupIngress{
|
||||
Description: "SSH traffic",
|
||||
SecurityGroupID: securityGroup.ID,
|
||||
CidrList: []string{"0.0.0.0/0"},
|
||||
CidrList: []CIDR{
|
||||
*egoscale.MustParseCIDR("0.0.0.0/0"),
|
||||
*egoscale.MustParseCIDR("::/0"),
|
||||
},
|
||||
Protocol: "tcp",
|
||||
StartPort: 22,
|
||||
EndPort: 22,
|
||||
|
@ -117,32 +120,32 @@ Security Groups provide a way to isolate traffic to VMs. Rules are added via the
|
|||
})
|
||||
// ...
|
||||
|
||||
Security Group also implement the generic List, Get and Delete interfaces (Listable, Gettable and Deletable).
|
||||
Security Group also implement the generic List, Get and Delete interfaces (Listable and Deletable).
|
||||
|
||||
// List all Security Groups
|
||||
sgs, err := cs.List(new(egoscale.SecurityGroup))
|
||||
sgs, _ := cs.List(&egoscale.SecurityGroup{})
|
||||
for _, s := range sgs {
|
||||
sg := s.(egoscale.SecurityGroup)
|
||||
// ...
|
||||
}
|
||||
|
||||
// Get a Security Group
|
||||
sg := &egoscale.SecurityGroup{Name: "Load balancer"}
|
||||
if err := cs.Get(sg); err != nil {
|
||||
sgQuery := &egoscale.SecurityGroup{Name: "Load balancer"}
|
||||
resp, err := cs.Get(sgQuery); err != nil {
|
||||
...
|
||||
}
|
||||
// The SecurityGroup struct has been loaded with the SecurityGroup informations
|
||||
sg := resp.(*egoscale.SecurityGroup)
|
||||
|
||||
if err := cs.Delete(sg); err != nil {
|
||||
...
|
||||
}
|
||||
// The SecurityGroup has been deleted
|
||||
|
||||
See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/networking_and_traffic.html#security-groups
|
||||
See: https://community.exoscale.com/documentation/compute/security-groups/
|
||||
|
||||
Zones
|
||||
|
||||
A Zone corresponds to a Data Center. You may list them. Zone implements the Listable interface, which let you perform a list in two different ways. The first exposes the underlying CloudStack request while the second one hide them and you only manipulate the structs of your interest.
|
||||
A Zone corresponds to a Data Center. You may list them. Zone implements the Listable interface, which let you perform a list in two different ways. The first exposes the underlying request while the second one hide them and you only manipulate the structs of your interest.
|
||||
|
||||
// Using ListZones request
|
||||
req := &egoscale.ListZones{}
|
||||
|
@ -171,7 +174,7 @@ Elastic IPs
|
|||
|
||||
An Elastic IP is a way to attach an IP address to many Virtual Machines. The API side of the story configures the external environment, like the routing. Some work is required within the machine to properly configure the interfaces.
|
||||
|
||||
See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/networking_and_traffic.html#about-elastic-ips
|
||||
See: https://community.exoscale.com/documentation/compute/eip/
|
||||
|
||||
*/
|
||||
package egoscale
|
||||
|
|
40
vendor/github.com/exoscale/egoscale/events.go
generated
vendored
40
vendor/github.com/exoscale/egoscale/events.go
generated
vendored
|
@ -5,9 +5,7 @@ type Event struct {
|
|||
Account string `json:"account,omitempty" doc:"the account name for the account that owns the object being acted on in the event (e.g. the owner of the virtual machine, ip address, or security group)"`
|
||||
Created string `json:"created,omitempty" doc:"the date the event was created"`
|
||||
Description string `json:"description,omitempty" doc:"a brief description of the event"`
|
||||
Domain string `json:"domain,omitempty" doc:"the name of the account's domain"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the id of the account's domain"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the ID of the event"`
|
||||
ID *UUID `json:"id" doc:"the ID of the event"`
|
||||
Level string `json:"level,omitempty" doc:"the event level (INFO, WARN, ERROR)"`
|
||||
ParentID *UUID `json:"parentid,omitempty" doc:"whether the event is parented"`
|
||||
State string `json:"state,omitempty" doc:"the state of the event"`
|
||||
|
@ -15,24 +13,40 @@ type Event struct {
|
|||
UserName string `json:"username,omitempty" doc:"the name of the user who performed the action (can be different from the account if an admin is performing an action for a user, e.g. starting/stopping a user's virtual machine)"`
|
||||
}
|
||||
|
||||
// ListRequest builds the ListEvents request
|
||||
func (event Event) ListRequest() (ListCommand, error) {
|
||||
req := &ListEvents{
|
||||
ID: event.ID,
|
||||
Level: event.Level,
|
||||
Type: event.Type,
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// EventType represent a type of event
|
||||
type EventType struct {
|
||||
Name string `json:"name,omitempty" doc:"Event Type"`
|
||||
}
|
||||
|
||||
// ListRequest builds the ListEventTypes request
|
||||
func (EventType) ListRequest() (ListCommand, error) {
|
||||
req := &ListEventTypes{}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListEvents
|
||||
|
||||
// ListEvents list the events
|
||||
type ListEvents struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
Duration int `json:"duration,omitempty" doc:"the duration of the event"`
|
||||
EndDate string `json:"enddate,omitempty" doc:"the end date range of the list you want to retrieve (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\")"`
|
||||
EntryTime int `json:"entrytime,omitempty" doc:"the time the event was entered"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the ID of the event"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves." doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
Level string `json:"level,omitempty" doc:"the event level (INFO, WARN, ERROR)"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Page int `json:"page,omitempty" `
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
StartDate string `json:"startdate,omitempty" doc:"the start date range of the list you want to retrieve (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\")"`
|
||||
Type string `json:"type,omitempty" doc:"the event type (see event types)"`
|
||||
|
@ -45,12 +59,12 @@ type ListEventsResponse struct {
|
|||
Event []Event `json:"event"`
|
||||
}
|
||||
|
||||
func (ListEvents) response() interface{} {
|
||||
return new(ListEventsResponse)
|
||||
}
|
||||
//go:generate go run generate/main.go -interface=Listable ListEventTypes
|
||||
|
||||
// ListEventTypes list the event types
|
||||
type ListEventTypes struct {
|
||||
Page int `json:"page,omitempty"` // fake
|
||||
PageSize int `json:"pagesize,omitempty"` // fake
|
||||
_ bool `name:"listEventTypes" description:"List Event Types"`
|
||||
}
|
||||
|
||||
|
@ -60,7 +74,3 @@ type ListEventTypesResponse struct {
|
|||
EventType []EventType `json:"eventtype"`
|
||||
_ bool `name:"listEventTypes" description:"List Event Types"`
|
||||
}
|
||||
|
||||
func (ListEventTypes) response() interface{} {
|
||||
return new(ListEventTypesResponse)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/events_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/events_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListEvents) Response() interface{} {
|
||||
return new(ListEventsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListEvents) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListEvents) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListEvents) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListEvents) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListEventsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListEventsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.Event {
|
||||
if !callback(&items.Event[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
43
vendor/github.com/exoscale/egoscale/eventtypes_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/eventtypes_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListEventTypes) Response() interface{} {
|
||||
return new(ListEventTypesResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListEventTypes) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListEventTypes) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListEventTypes) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListEventTypes) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListEventTypesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListEventTypesResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.EventType {
|
||||
if !callback(&items.EventType[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
99
vendor/github.com/exoscale/egoscale/hosts.go
generated
vendored
99
vendor/github.com/exoscale/egoscale/hosts.go
generated
vendored
|
@ -1,99 +0,0 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
// Host represents the Hypervisor
|
||||
type Host struct {
|
||||
Capabilities string `json:"capabilities,omitempty" doc:"capabilities of the host"`
|
||||
ClusterID *UUID `json:"clusterid,omitempty" doc:"the cluster ID of the host"`
|
||||
ClusterName string `json:"clustername,omitempty" doc:"the cluster name of the host"`
|
||||
ClusterType string `json:"clustertype,omitempty" doc:"the cluster type of the cluster that host belongs to"`
|
||||
CPUAllocated int64 `json:"cpuallocated,omitempty" doc:"the amount of the host's CPU currently allocated"`
|
||||
CPUNumber int `json:"cpunumber,omitempty" doc:"the CPU number of the host"`
|
||||
CPUSockets int `json:"cpusockets,omitempty" doc:"the number of CPU sockets on the host"`
|
||||
CPUSpeed int64 `json:"cpuspeed,omitempty" doc:"the CPU speed of the host"`
|
||||
CPUUsed int64 `json:"cpuused,omitempty" doc:"the amount of the host's CPU currently used"`
|
||||
CPUWithOverProvisioning int64 `json:"cpuwithoverprovisioning,omitempty" doc:"the amount of the host's CPU after applying the cpu.overprovisioning.factor"`
|
||||
Created string `json:"created,omitempty" doc:"the date and time the host was created"`
|
||||
Disconnected string `json:"disconnected,omitempty" doc:"true if the host is disconnected. False otherwise."`
|
||||
DiskSizeAllocated int64 `json:"disksizeallocated,omitempty" doc:"the host's or host storage pool's currently allocated disk size"`
|
||||
DiskSizeTotal int64 `json:"disksizetotal,omitempty" doc:"the total disk size of the host or host storage pool"`
|
||||
DiskSizeUsed int64 `json:"disksizeused,omitempty" doc:"the host's or host storage pool's currently used disk size"`
|
||||
DiskWithOverProvisioning int64 `json:"diskwithoverprovisioning,omitempty" doc:"the total disk size of the host or host storage pool with over provisioning factor"`
|
||||
Events string `json:"events,omitempty" doc:"events available for the host"`
|
||||
HAHost *bool `json:"hahost,omitempty" doc:"true if the host is Ha host (dedicated to vms started by HA process; false otherwise"`
|
||||
HostTags string `json:"hosttags,omitempty" doc:"comma-separated list of tags for the host"`
|
||||
Hypervisor string `json:"hypervisor,omitempty" doc:"the host hypervisor"`
|
||||
HypervisorVersion string `json:"hypervisorversion,omitempty" doc:"the hypervisor version"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the ID of the host"`
|
||||
IPAddress net.IP `json:"ipaddress,omitempty" doc:"the IP address of the host"`
|
||||
IsLocalstorageActive *bool `json:"islocalstorageactive,omitempty" doc:"true if local storage is active, false otherwise"`
|
||||
LastPinged string `json:"lastpinged,omitempty" doc:"the date and time the host was last pinged"`
|
||||
ManagementServerID *UUID `json:"managementserverid,omitempty" doc:"the management server ID of the host"`
|
||||
MemoryAllocated int64 `json:"memoryallocated,omitempty" doc:"the amount of VM's memory allocated onto the host"`
|
||||
MemoryPhysical int64 `json:"memoryphysical,omitempty" doc:"the total physical memory of the host"`
|
||||
MemoryReserved int64 `json:"memoryreserved,omitempty" doc:"the amount of the host's memory reserved"`
|
||||
MemoryTotal int64 `json:"memorytotal,omitempty" doc:"the total memory of the host available (must be physical - reserved)"`
|
||||
MemoryUsed int64 `json:"memoryused,omitempty" doc:"the amount of the host's memory used by running vm"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the host"`
|
||||
NetworkKbsRead int64 `json:"networkkbsread,omitempty" doc:"the incoming network traffic on the host"`
|
||||
NetworkKbsWrite int64 `json:"networkkbswrite,omitempty" doc:"the outgoing network traffic on the host"`
|
||||
OSCategoryID *UUID `json:"oscategoryid,omitempty" doc:"the OS category ID of the host"`
|
||||
OSCategoryName string `json:"oscategoryname,omitempty" doc:"the OS category name of the host"`
|
||||
PCIDevices []PCIDevice `json:"pcidevices,omitempty" doc:"PCI cards present in the host"`
|
||||
PodID *UUID `json:"podid,omitempty" doc:"the Pod ID of the host"`
|
||||
PodName string `json:"podname,omitempty" doc:"the Pod name of the host"`
|
||||
Removed string `json:"removed,omitempty" doc:"the date and time the host was removed"`
|
||||
ResourceState string `json:"resourcestate,omitempty" doc:"the resource state of the host"`
|
||||
State string `json:"state,omitempty" doc:"the state of the host"`
|
||||
StorageID *UUID `json:"storageid,omitempty" doc:"the host's storage pool id"`
|
||||
Type string `json:"type,omitempty" doc:"the host type"`
|
||||
Version string `json:"version,omitempty" doc:"the host version"`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"the Zone ID of the host"`
|
||||
ZoneName string `json:"zonename,omitempty" doc:"the Zone name of the host"`
|
||||
}
|
||||
|
||||
// ListHosts lists hosts
|
||||
type ListHosts struct {
|
||||
ClusterID *UUID `json:"clusterid,omitempty" doc:"lists hosts existing in particular cluster"`
|
||||
Details []string `json:"details,omitempty" doc:"comma separated list of host details requested, value can be a list of [ min, all, capacity, events, stats]"`
|
||||
HAHost *bool `json:"hahost,omitempty" doc:"if true, list only hosts dedicated to HA"`
|
||||
Hypervisor string `json:"hypervisor,omitempty" doc:"hypervisor type of host: KVM,Simulator"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the id of the host"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the host"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
PodID *UUID `json:"podid,omitempty" doc:"the Pod ID for the host"`
|
||||
ResourceState string `json:"resourcestate,omitempty" doc:"list hosts by resource state. Resource state represents current state determined by admin of host, value can be one of [Enabled, Disabled, Unmanaged, PrepareForMaintenance, ErrorInMaintenance, Maintenance, Error]"`
|
||||
State string `json:"state,omitempty" doc:"the state of the host"`
|
||||
Type string `json:"type,omitempty" doc:"the host type"`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"the Zone ID for the host"`
|
||||
_ bool `name:"listHosts" description:"Lists hosts."`
|
||||
}
|
||||
|
||||
func (ListHosts) response() interface{} {
|
||||
return new(ListHostsResponse)
|
||||
}
|
||||
|
||||
// ListHostsResponse represents a list of hosts
|
||||
type ListHostsResponse struct {
|
||||
Count int `json:"count"`
|
||||
Host []Host `json:"host"`
|
||||
}
|
||||
|
||||
// UpdateHost changes the resources state of a host
|
||||
type UpdateHost struct {
|
||||
Allocationstate string `json:"allocationstate,omitempty" doc:"Change resource state of host, valid values are [Enable, Disable]. Operation may failed if host in states not allowing Enable/Disable"`
|
||||
HostTags []string `json:"hosttags,omitempty" doc:"list of tags to be added to the host"`
|
||||
ID *UUID `json:"id" doc:"the ID of the host to update"`
|
||||
OSCategoryID *UUID `json:"oscategoryid,omitempty" doc:"the id of Os category to update the host with"`
|
||||
URL string `json:"url,omitempty" doc:"the new uri for the secondary storage: nfs://host/path"`
|
||||
_ bool `name:"updateHost" description:"Updates a host."`
|
||||
}
|
||||
|
||||
func (UpdateHost) response() interface{} {
|
||||
return new(Host)
|
||||
}
|
71
vendor/github.com/exoscale/egoscale/instance_groups.go
generated
vendored
Normal file
71
vendor/github.com/exoscale/egoscale/instance_groups.go
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
package egoscale
|
||||
|
||||
// InstanceGroup represents a group of VM
|
||||
type InstanceGroup struct {
|
||||
Account string `json:"account,omitempty" doc:"the account owning the instance group"`
|
||||
Created string `json:"created,omitempty" doc:"time and date the instance group was created"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the id of the instance group"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the instance group"`
|
||||
}
|
||||
|
||||
// ListRequest builds the ListInstanceGroups request
|
||||
func (ig InstanceGroup) ListRequest() (ListCommand, error) {
|
||||
req := &ListInstanceGroups{
|
||||
ID: ig.ID,
|
||||
Name: ig.Name,
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// CreateInstanceGroup creates a VM group
|
||||
type CreateInstanceGroup struct {
|
||||
Name string `json:"name" doc:"the name of the instance group"`
|
||||
_ bool `name:"createInstanceGroup" description:"Creates a vm group"`
|
||||
}
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (CreateInstanceGroup) Response() interface{} {
|
||||
return new(InstanceGroup)
|
||||
}
|
||||
|
||||
// UpdateInstanceGroup updates a VM group
|
||||
type UpdateInstanceGroup struct {
|
||||
ID *UUID `json:"id" doc:"Instance group ID"`
|
||||
Name string `json:"name,omitempty" doc:"new instance group name"`
|
||||
_ bool `name:"updateInstanceGroup" description:"Updates a vm group"`
|
||||
}
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (UpdateInstanceGroup) Response() interface{} {
|
||||
return new(InstanceGroup)
|
||||
}
|
||||
|
||||
// DeleteInstanceGroup deletes a VM group
|
||||
type DeleteInstanceGroup struct {
|
||||
ID *UUID `json:"id" doc:"the ID of the instance group"`
|
||||
_ bool `name:"deleteInstanceGroup" description:"Deletes a vm group"`
|
||||
}
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (DeleteInstanceGroup) Response() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListInstanceGroups
|
||||
|
||||
// ListInstanceGroups lists VM groups
|
||||
type ListInstanceGroups struct {
|
||||
ID *UUID `json:"id,omitempty" doc:"List instance groups by ID"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
Name string `json:"name,omitempty" doc:"List instance groups by name"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
_ bool `name:"listInstanceGroups" description:"Lists vm groups"`
|
||||
}
|
||||
|
||||
// ListInstanceGroupsResponse represents a list of instance groups
|
||||
type ListInstanceGroupsResponse struct {
|
||||
Count int `json:"count"`
|
||||
InstanceGroup []InstanceGroup `json:"instancegroup"`
|
||||
}
|
43
vendor/github.com/exoscale/egoscale/instancegroups_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/instancegroups_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListInstanceGroups) Response() interface{} {
|
||||
return new(ListInstanceGroupsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListInstanceGroups) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListInstanceGroups) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListInstanceGroups) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListInstanceGroups) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListInstanceGroupsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListInstanceGroupsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.InstanceGroup {
|
||||
if !callback(&items.InstanceGroup[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
94
vendor/github.com/exoscale/egoscale/isos.go
generated
vendored
Normal file
94
vendor/github.com/exoscale/egoscale/isos.go
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
package egoscale
|
||||
|
||||
// ISO represents an attachable ISO disc
|
||||
type ISO Template
|
||||
|
||||
// ResourceType returns the type of the resource
|
||||
func (ISO) ResourceType() string {
|
||||
return "ISO"
|
||||
}
|
||||
|
||||
// ListRequest produces the ListIsos command.
|
||||
func (iso ISO) ListRequest() (ListCommand, error) {
|
||||
req := &ListISOs{
|
||||
ID: iso.ID,
|
||||
Name: iso.Name,
|
||||
ZoneID: iso.ZoneID,
|
||||
}
|
||||
if iso.Bootable {
|
||||
*req.Bootable = true
|
||||
}
|
||||
if iso.IsFeatured {
|
||||
req.IsoFilter = "featured"
|
||||
}
|
||||
if iso.IsPublic {
|
||||
*req.IsPublic = true
|
||||
}
|
||||
if iso.IsReady {
|
||||
*req.IsReady = true
|
||||
}
|
||||
|
||||
for i := range iso.Tags {
|
||||
req.Tags = append(req.Tags, iso.Tags[i])
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListISOs
|
||||
|
||||
// ListISOs represents the list all available ISO files request
|
||||
type ListISOs struct {
|
||||
_ bool `name:"listIsos" description:"Lists all available ISO files."`
|
||||
Bootable *bool `json:"bootable,omitempty" doc:"True if the ISO is bootable, false otherwise"`
|
||||
ID *UUID `json:"id,omitempty" doc:"List ISO by id"`
|
||||
IsoFilter string `json:"isofilter,omitempty" doc:"Possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". * featured : templates that have been marked as featured and public. * self : templates that have been registered or created by the calling user. * selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. * sharedexecutable : templates ready to be deployed that have been granted to the calling user by another user. * executable : templates that are owned by the calling user, or public templates, that can be used to deploy a VM. * community : templates that have been marked as public but not featured. * all : all templates (only usable by admins)."`
|
||||
IsPublic *bool `json:"ispublic,omitempty" doc:"True if the ISO is publicly available to all users, false otherwise."`
|
||||
IsReady *bool `json:"isready,omitempty" doc:"True if this ISO is ready to be deployed"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
Name string `json:"name,omitempty" doc:"List all isos by name"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
ShowRemoved *bool `json:"showremoved,omitempty" doc:"Show removed ISOs as well"`
|
||||
Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"The ID of the zone"`
|
||||
}
|
||||
|
||||
// ListISOsResponse represents a list of ISO files
|
||||
type ListISOsResponse struct {
|
||||
Count int `json:"count"`
|
||||
ISO []ISO `json:"iso"`
|
||||
}
|
||||
|
||||
// AttachISO represents the request to attach an ISO to a virtual machine.
|
||||
type AttachISO struct {
|
||||
_ bool `name:"attachIso" description:"Attaches an ISO to a virtual machine."`
|
||||
ID *UUID `json:"id" doc:"the ID of the ISO file"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid" doc:"the ID of the virtual machine"`
|
||||
}
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (AttachISO) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (AttachISO) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
// DetachISO represents the request to detach an ISO to a virtual machine.
|
||||
type DetachISO struct {
|
||||
_ bool `name:"detachIso" description:"Detaches any ISO file (if any) currently attached to a virtual machine."`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid" doc:"The ID of the virtual machine"`
|
||||
}
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (DetachISO) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (DetachISO) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
43
vendor/github.com/exoscale/egoscale/isos_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/isos_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListISOs) Response() interface{} {
|
||||
return new(ListISOsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListISOs) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListISOs) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListISOs) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListISOs) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListISOsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListISOsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.ISO {
|
||||
if !callback(&items.ISO[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
139
vendor/github.com/exoscale/egoscale/limits.go
generated
vendored
139
vendor/github.com/exoscale/egoscale/limits.go
generated
vendored
|
@ -1,139 +0,0 @@
|
|||
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 ResourceTypeName = "public_ip"
|
||||
// VolumeTypeName is the resource type name of a volume
|
||||
VolumeTypeName ResourceTypeName = "volume"
|
||||
// SnapshotTypeName is the resource type name of a snapshot
|
||||
SnapshotTypeName ResourceTypeName = "snapshot"
|
||||
// TemplateTypeName is the resource type name of a template
|
||||
TemplateTypeName ResourceTypeName = "template"
|
||||
// ProjectTypeName is the resource type name of a project
|
||||
ProjectTypeName ResourceTypeName = "project"
|
||||
// NetworkTypeName is the resource type name of a network
|
||||
NetworkTypeName ResourceTypeName = "network"
|
||||
// VPCTypeName is the resource type name of a VPC
|
||||
VPCTypeName ResourceTypeName = "vpc"
|
||||
// CPUTypeName is the resource type name of a CPU
|
||||
CPUTypeName ResourceTypeName = "cpu"
|
||||
// MemoryTypeName is the resource type name of Memory
|
||||
MemoryTypeName ResourceTypeName = "memory"
|
||||
// PrimaryStorageTypeName is the resource type name of primary storage
|
||||
PrimaryStorageTypeName ResourceTypeName = "primary_storage"
|
||||
// SecondaryStorageTypeName is the resource type name of secondary storage
|
||||
SecondaryStorageTypeName ResourceTypeName = "secondary_storage"
|
||||
)
|
||||
|
||||
// ResourceType represents the ID of a resource type (for limits)
|
||||
type ResourceType string
|
||||
|
||||
const (
|
||||
// VirtualMachineType is the resource type ID of a VM
|
||||
VirtualMachineType ResourceType = "0"
|
||||
// IPAddressType is the resource type ID of an IP address
|
||||
IPAddressType ResourceType = "1"
|
||||
// VolumeType is the resource type ID of a volume
|
||||
VolumeType ResourceType = "2"
|
||||
// SnapshotType is the resource type ID of a snapshot
|
||||
SnapshotType ResourceType = "3"
|
||||
// TemplateType is the resource type ID of a template
|
||||
TemplateType ResourceType = "4"
|
||||
// ProjectType is the resource type ID of a project
|
||||
ProjectType ResourceType = "5"
|
||||
// NetworkType is the resource type ID of a network
|
||||
NetworkType ResourceType = "6"
|
||||
// VPCType is the resource type ID of a VPC
|
||||
VPCType ResourceType = "7"
|
||||
// CPUType is the resource type ID of a CPU
|
||||
CPUType ResourceType = "8"
|
||||
// MemoryType is the resource type ID of Memory
|
||||
MemoryType ResourceType = "9"
|
||||
// PrimaryStorageType is the resource type ID of primary storage
|
||||
PrimaryStorageType ResourceType = "10"
|
||||
// SecondaryStorageType is the resource type ID of secondary storage
|
||||
SecondaryStorageType ResourceType = "11"
|
||||
)
|
||||
|
||||
// ResourceLimit represents the limit on a particular resource
|
||||
type ResourceLimit struct {
|
||||
Account string `json:"account,omitempty" doc:"the account of the resource limit"`
|
||||
Domain string `json:"domain,omitempty" doc:"the domain name of the resource limit"`
|
||||
DomainID string `json:"domainid,omitempty" doc:"the domain ID of the resource limit"`
|
||||
Max int64 `json:"max,omitempty" doc:"the maximum number of the resource. A -1 means the resource currently has no limit."`
|
||||
ResourceType ResourceType `json:"resourcetype,omitempty" doc:"resource type. Values include 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11. See the resourceType parameter for more information on these values."`
|
||||
ResourceTypeName string `json:"resourcetypename,omitempty" doc:"resource type name. Values include user_vm, public_ip, volume, snapshot, template, project, network, vpc, cpu, memory, primary_storage, secondary_storage."`
|
||||
}
|
||||
|
||||
// APILimit represents the limit count
|
||||
type APILimit struct {
|
||||
Account string `json:"account,omitempty" doc:"the account name of the api remaining count"`
|
||||
Accountid string `json:"accountid,omitempty" doc:"the account uuid of the api remaining count"`
|
||||
APIAllowed int `json:"apiAllowed,omitempty" doc:"currently allowed number of apis"`
|
||||
APIIssued int `json:"apiIssued,omitempty" doc:"number of api already issued"`
|
||||
ExpireAfter int64 `json:"expireAfter,omitempty" doc:"seconds left to reset counters"`
|
||||
}
|
||||
|
||||
// ListResourceLimits lists the resource limits
|
||||
type ListResourceLimits struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DomainID string `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ID int64 `json:"id,omitempty" doc:"Lists resource limits by ID."`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
ResourceType ResourceType `json:"resourcetype,omitempty" doc:"Type of resource. Values are 0, 1, 2, 3, 4, 6, 7, 8, 9, 10 and 11. 0 - Instance. Number of instances a user can create. 1 - IP. Number of public IP addresses an account can own. 2 - Volume. Number of disk volumes an account can own. 3 - Snapshot. Number of snapshots an account can own. 4 - Template. Number of templates an account can register/create. 5 - Project. Number of projects an account can own. 6 - Network. Number of networks an account can own. 7 - VPC. Number of VPC an account can own. 8 - CPU. Number of CPU an account can allocate for his resources. 9 - Memory. Amount of RAM an account can allocate for his resources. 10 - PrimaryStorage. Total primary storage space (in GiB) a user can use. 11 - SecondaryStorage. Total secondary storage space (in GiB) a user can use. 12 - Elastic IP. Number of public elastic IP addresses an account can own. 13 - SMTP. If the account is allowed SMTP outbound traffic."`
|
||||
ResourceTypeName string `json:"resourcetypename,omitempty" doc:"Type of resource (wins over resourceType if both are provided). Values are: user_vm - Instance. Number of instances a user can create. public_ip - IP. Number of public IP addresses an account can own. volume - Volume. Number of disk volumes an account can own. snapshot - Snapshot. Number of snapshots an account can own. template - Template. Number of templates an account can register/create. project - Project. Number of projects an account can own. network - Network. Number of networks an account can own. vpc - VPC. Number of VPC an account can own. cpu - CPU. Number of CPU an account can allocate for his resources. memory - Memory. Amount of RAM an account can allocate for his resources. primary_storage - PrimaryStorage. Total primary storage space (in GiB) a user can use. secondary_storage - SecondaryStorage. Total secondary storage space (in GiB) a user can use. public_elastic_ip - IP. Number of public elastic IP addresses an account can own. smtp - SG. If the account is allowed SMTP outbound traffic."`
|
||||
_ bool `name:"listResourceLimits" description:"Lists resource limits."`
|
||||
}
|
||||
|
||||
// ListResourceLimitsResponse represents a list of resource limits
|
||||
type ListResourceLimitsResponse struct {
|
||||
Count int `json:"count"`
|
||||
ResourceLimit []ResourceLimit `json:"resourcelimit"`
|
||||
}
|
||||
|
||||
func (ListResourceLimits) response() interface{} {
|
||||
return new(ListResourceLimitsResponse)
|
||||
}
|
||||
|
||||
// UpdateResourceLimit updates the resource limit
|
||||
type UpdateResourceLimit struct {
|
||||
Account string `json:"account,omitempty" doc:"Update resource for a specified account. Must be used with the domainId parameter."`
|
||||
DomainID string `json:"domainid,omitempty" doc:"Update resource limits for all accounts in specified domain. If used with the account parameter, updates resource limits for a specified account in specified domain."`
|
||||
Max int64 `json:"max,omitempty" doc:"Maximum resource limit."`
|
||||
ResourceType ResourceType `json:"resourcetype" doc:"Type of resource to update. Values are 0, 1, 2, 3, 4, 6, 7, 8, 9, 10 and 11. 0 - Instance. Number of instances a user can create. 1 - IP. Number of public IP addresses a user can own. 2 - Volume. Number of disk volumes a user can create. 3 - Snapshot. Number of snapshots a user can create. 4 - Template. Number of templates that a user can register/create. 6 - Network. Number of guest network a user can create. 7 - VPC. Number of VPC a user can create. 8 - CPU. Total number of CPU cores a user can use. 9 - Memory. Total Memory (in MB) a user can use. 10 - PrimaryStorage. Total primary storage space (in GiB) a user can use. 11 - SecondaryStorage. Total secondary storage space (in GiB) a user can use."`
|
||||
_ bool `name:"updateResourceLimit" description:"Updates resource limits for an account or domain."`
|
||||
}
|
||||
|
||||
// UpdateResourceLimitResponse represents an updated resource limit
|
||||
type UpdateResourceLimitResponse struct {
|
||||
ResourceLimit ResourceLimit `json:"resourcelimit"`
|
||||
}
|
||||
|
||||
func (UpdateResourceLimit) response() interface{} {
|
||||
return new(UpdateResourceLimitResponse)
|
||||
}
|
||||
|
||||
// GetAPILimit gets API limit count for the caller
|
||||
type GetAPILimit struct {
|
||||
_ bool `name:"getApiLimit" description:"Get API limit count for the caller"`
|
||||
}
|
||||
|
||||
// GetAPILimitResponse represents the limits towards the API call
|
||||
type GetAPILimitResponse struct {
|
||||
APILimit APILimit `json:"apilimit"`
|
||||
}
|
||||
|
||||
func (GetAPILimit) response() interface{} {
|
||||
return new(GetAPILimitResponse)
|
||||
}
|
24
vendor/github.com/exoscale/egoscale/network_offerings.go
generated
vendored
24
vendor/github.com/exoscale/egoscale/network_offerings.go
generated
vendored
|
@ -25,6 +25,23 @@ type NetworkOffering struct {
|
|||
TrafficType string `json:"traffictype,omitempty" doc:"the traffic type for the network offering, supported types are Public, Management, Control, Guest, Vlan or Storage."`
|
||||
}
|
||||
|
||||
// ListRequest builds the ListNetworkOfferings request
|
||||
//
|
||||
// This doesn't take into account the IsDefault flag as the default value is true.
|
||||
func (no NetworkOffering) ListRequest() (ListCommand, error) {
|
||||
req := &ListNetworkOfferings{
|
||||
Availability: no.Availability,
|
||||
ID: no.ID,
|
||||
Name: no.Name,
|
||||
State: no.State,
|
||||
TrafficType: no.TrafficType,
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListNetworkOfferings
|
||||
|
||||
// ListNetworkOfferings represents a query for network offerings
|
||||
type ListNetworkOfferings struct {
|
||||
Availability string `json:"availability,omitempty" doc:"the availability of network offering. Default value is Required"`
|
||||
|
@ -55,10 +72,6 @@ type ListNetworkOfferingsResponse struct {
|
|||
NetworkOffering []NetworkOffering `json:"networkoffering"`
|
||||
}
|
||||
|
||||
func (ListNetworkOfferings) response() interface{} {
|
||||
return new(ListNetworkOfferingsResponse)
|
||||
}
|
||||
|
||||
// UpdateNetworkOffering represents a modification of a network offering
|
||||
type UpdateNetworkOffering struct {
|
||||
Availability string `json:"availability,omitempty" doc:"the availability of network offering. Default value is Required for Guest Virtual network offering; Optional for Guest Direct network offering"`
|
||||
|
@ -72,6 +85,7 @@ type UpdateNetworkOffering struct {
|
|||
_ bool `name:"updateNetworkOffering" description:"Updates a network offering."`
|
||||
}
|
||||
|
||||
func (UpdateNetworkOffering) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (UpdateNetworkOffering) Response() interface{} {
|
||||
return new(NetworkOffering)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/networkofferings_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/networkofferings_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListNetworkOfferings) Response() interface{} {
|
||||
return new(ListNetworkOfferingsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListNetworkOfferings) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListNetworkOfferings) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListNetworkOfferings) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListNetworkOfferings) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListNetworkOfferingsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListNetworkOfferingsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.NetworkOffering {
|
||||
if !callback(&items.NetworkOffering[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
97
vendor/github.com/exoscale/egoscale/networks.go
generated
vendored
97
vendor/github.com/exoscale/egoscale/networks.go
generated
vendored
|
@ -1,7 +1,6 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
)
|
||||
|
@ -16,12 +15,9 @@ type Network struct {
|
|||
BroadcastURI string `json:"broadcasturi,omitempty" doc:"broadcast uri of the network."`
|
||||
CanUseForDeploy bool `json:"canusefordeploy,omitempty" doc:"list networks available for vm deployment"`
|
||||
CIDR *CIDR `json:"cidr,omitempty" doc:"Cloudstack managed address space, all CloudStack managed VMs get IP address from CIDR"`
|
||||
DisplayNetwork bool `json:"displaynetwork,omitempty" doc:"an optional field, whether to the display the network to the end user or not."`
|
||||
DisplayText string `json:"displaytext,omitempty" doc:"the displaytext of the network"`
|
||||
DNS1 net.IP `json:"dns1,omitempty" doc:"the first DNS for the network"`
|
||||
DNS2 net.IP `json:"dns2,omitempty" doc:"the second DNS for the network"`
|
||||
Domain string `json:"domain,omitempty" doc:"the domain name of the network owner"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain id of the network owner"`
|
||||
EndIP net.IP `json:"endip,omitempty" doc:"the ending IP address in the network IP range. Required for managed networks."`
|
||||
Gateway net.IP `json:"gateway,omitempty" doc:"the network's gateway"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the id of the network"`
|
||||
|
@ -62,8 +58,6 @@ type Network struct {
|
|||
func (network Network) ListRequest() (ListCommand, error) {
|
||||
//TODO add tags support
|
||||
req := &ListNetworks{
|
||||
Account: network.Account,
|
||||
DomainID: network.DomainID,
|
||||
ID: network.ID,
|
||||
Keyword: network.Name, // this is a hack as listNetworks doesn't support to search by name.
|
||||
PhysicalNetworkID: network.PhysicalNetworkID,
|
||||
|
@ -113,10 +107,7 @@ type ServiceProvider struct {
|
|||
|
||||
// CreateNetwork creates a network
|
||||
type CreateNetwork struct {
|
||||
Account string `json:"account,omitempty" doc:"account who will own the network"`
|
||||
DisplayNetwork *bool `json:"displaynetwork,omitempty" doc:"an optional field, whether to the display the network to the end user or not."`
|
||||
DisplayText string `json:"displaytext,omitempty" doc:"the display text of the network"` // This field is required but might be empty
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"domain ID of the account owning a network"`
|
||||
EndIP net.IP `json:"endip,omitempty" doc:"the ending IP address in the network IP range. Required for managed networks."`
|
||||
EndIpv6 net.IP `json:"endipv6,omitempty" doc:"the ending IPv6 address in the IPv6 network range"`
|
||||
Gateway net.IP `json:"gateway,omitempty" doc:"the gateway of the network. Required for Shared networks and Isolated networks when it belongs to VPC"`
|
||||
|
@ -130,13 +121,13 @@ type CreateNetwork struct {
|
|||
PhysicalNetworkID *UUID `json:"physicalnetworkid,omitempty" doc:"the Physical Network ID the network belongs to"`
|
||||
StartIP net.IP `json:"startip,omitempty" doc:"the beginning IP address in the network IP range. Required for managed networks."`
|
||||
StartIpv6 net.IP `json:"startipv6,omitempty" doc:"the beginning IPv6 address in the IPv6 network range"`
|
||||
SubdomainAccess *bool `json:"subdomainaccess,omitempty" doc:"Defines whether to allow subdomains to use networks dedicated to their parent domain(s). Should be used with aclType=Domain, defaulted to allow.subdomain.network.access global config if not specified"`
|
||||
Vlan string `json:"vlan,omitempty" doc:"the ID or VID of the network"`
|
||||
ZoneID *UUID `json:"zoneid" doc:"the Zone ID for the network"`
|
||||
_ bool `name:"createNetwork" description:"Creates a network"`
|
||||
}
|
||||
|
||||
func (CreateNetwork) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (CreateNetwork) Response() interface{} {
|
||||
return new(Network)
|
||||
}
|
||||
|
||||
|
@ -153,23 +144,26 @@ func (req CreateNetwork) onBeforeSend(params url.Values) error {
|
|||
|
||||
// UpdateNetwork (Async) updates a network
|
||||
type UpdateNetwork struct {
|
||||
ID *UUID `json:"id" doc:"the ID of the network"`
|
||||
_ bool `name:"updateNetwork" description:"Updates a network"`
|
||||
ChangeCIDR *bool `json:"changecidr,omitempty" doc:"Force update even if cidr type is different"`
|
||||
CustomID *UUID `json:"customid,omitempty" doc:"an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only"`
|
||||
DisplayNetwork *bool `json:"displaynetwork,omitempty" doc:"an optional field, whether to the display the network to the end user or not."`
|
||||
DisplayText string `json:"displaytext,omitempty" doc:"the new display text for the network"`
|
||||
EndIP net.IP `json:"endip,omitempty" doc:"the ending IP address in the network IP range. Required for managed networks."`
|
||||
GuestVMCIDR *CIDR `json:"guestvmcidr,omitempty" doc:"CIDR for Guest VMs,Cloudstack allocates IPs to Guest VMs only from this CIDR"`
|
||||
ID *UUID `json:"id" doc:"the ID of the network"`
|
||||
Name string `json:"name,omitempty" doc:"the new name for the network"`
|
||||
Netmask net.IP `json:"netmask,omitempty" doc:"the netmask of the network. Required for managed networks."`
|
||||
NetworkDomain string `json:"networkdomain,omitempty" doc:"network domain"`
|
||||
NetworkOfferingID *UUID `json:"networkofferingid,omitempty" doc:"network offering ID"`
|
||||
_ bool `name:"updateNetwork" description:"Updates a network"`
|
||||
StartIP net.IP `json:"startip,omitempty" doc:"the beginning IP address in the network IP range. Required for managed networks."`
|
||||
}
|
||||
|
||||
func (UpdateNetwork) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (UpdateNetwork) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (UpdateNetwork) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (UpdateNetwork) AsyncResponse() interface{} {
|
||||
return new(Network)
|
||||
}
|
||||
|
||||
|
@ -180,11 +174,13 @@ type RestartNetwork struct {
|
|||
_ bool `name:"restartNetwork" description:"Restarts the network; includes 1) restarting network elements - virtual routers, dhcp servers 2) reapplying all public ips 3) reapplying loadBalancing/portForwarding rules"`
|
||||
}
|
||||
|
||||
func (RestartNetwork) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RestartNetwork) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (RestartNetwork) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (RestartNetwork) AsyncResponse() interface{} {
|
||||
return new(Network)
|
||||
}
|
||||
|
||||
|
@ -195,35 +191,34 @@ type DeleteNetwork struct {
|
|||
_ bool `name:"deleteNetwork" description:"Deletes a network"`
|
||||
}
|
||||
|
||||
func (DeleteNetwork) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (DeleteNetwork) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (DeleteNetwork) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (DeleteNetwork) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListNetworks
|
||||
|
||||
// ListNetworks represents a query to a network
|
||||
type ListNetworks struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
CanUseForDeploy *bool `json:"canusefordeploy,omitempty" doc:"list networks available for vm deployment"`
|
||||
DisplayNetwork *bool `json:"displaynetwork,omitempty" doc:"list resources by display flag; only ROOT admin is eligible to pass this parameter"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ID *UUID `json:"id,omitempty" doc:"list networks by id"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
IsSystem *bool `json:"issystem,omitempty" doc:"true if network is system, false otherwise"`
|
||||
CanUseForDeploy *bool `json:"canusefordeploy,omitempty" doc:"List networks available for vm deployment"`
|
||||
ID *UUID `json:"id,omitempty" doc:"List networks by id"`
|
||||
IsSystem *bool `json:"issystem,omitempty" doc:"true If network is system, false otherwise"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
PhysicalNetworkID *UUID `json:"physicalnetworkid,omitempty" doc:"list networks by physical network id"`
|
||||
RestartRequired *bool `json:"restartrequired,omitempty" doc:"list networks by restartRequired"`
|
||||
SpecifyIPRanges *bool `json:"specifyipranges,omitempty" doc:"true if need to list only networks which support specifying ip ranges"`
|
||||
SupportedServices []Service `json:"supportedservices,omitempty" doc:"list networks supporting certain services"`
|
||||
PhysicalNetworkID *UUID `json:"physicalnetworkid,omitempty" doc:"List networks by physical network id"`
|
||||
RestartRequired *bool `json:"restartrequired,omitempty" doc:"List networks by restartRequired"`
|
||||
SpecifyIPRanges *bool `json:"specifyipranges,omitempty" doc:"True if need to list only networks which support specifying ip ranges"`
|
||||
SupportedServices []Service `json:"supportedservices,omitempty" doc:"List networks supporting certain services"`
|
||||
Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"`
|
||||
TrafficType string `json:"traffictype,omitempty" doc:"type of the traffic"`
|
||||
Type string `json:"type,omitempty" doc:"the type of the network. Supported values are: Isolated and Shared"`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"the Zone ID of the network"`
|
||||
TrafficType string `json:"traffictype,omitempty" doc:"Type of the traffic"`
|
||||
Type string `json:"type,omitempty" doc:"The type of the network. Supported values are: Isolated and Shared"`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"The Zone ID of the network"`
|
||||
_ bool `name:"listNetworks" description:"Lists all available networks."`
|
||||
}
|
||||
|
||||
|
@ -232,31 +227,3 @@ type ListNetworksResponse struct {
|
|||
Count int `json:"count"`
|
||||
Network []Network `json:"network"`
|
||||
}
|
||||
|
||||
func (ListNetworks) response() interface{} {
|
||||
return new(ListNetworksResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (listNetwork *ListNetworks) SetPage(page int) {
|
||||
listNetwork.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (listNetwork *ListNetworks) SetPageSize(pageSize int) {
|
||||
listNetwork.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListNetworks) each(resp interface{}, callback IterateItemFunc) {
|
||||
networks, ok := resp.(*ListNetworksResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("type error: ListNetworksResponse expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range networks.Network {
|
||||
if !callback(&networks.Network[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/networks_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/networks_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListNetworks) Response() interface{} {
|
||||
return new(ListNetworksResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListNetworks) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListNetworks) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListNetworks) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListNetworks) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListNetworksResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListNetworksResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.Network {
|
||||
if !callback(&items.Network[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
53
vendor/github.com/exoscale/egoscale/nics.go
generated
vendored
53
vendor/github.com/exoscale/egoscale/nics.go
generated
vendored
|
@ -1,7 +1,6 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
|
@ -32,10 +31,6 @@ type Nic struct {
|
|||
|
||||
// ListRequest build a ListNics request from the given Nic
|
||||
func (nic Nic) ListRequest() (ListCommand, error) {
|
||||
if nic.VirtualMachineID == nil {
|
||||
return nil, errors.New("command ListNics requires the VirtualMachineID field to be set")
|
||||
}
|
||||
|
||||
req := &ListNics{
|
||||
VirtualMachineID: nic.VirtualMachineID,
|
||||
NicID: nic.ID,
|
||||
|
@ -54,15 +49,16 @@ type NicSecondaryIP struct {
|
|||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"the ID of the vm"`
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListNics
|
||||
|
||||
// ListNics represents the NIC search
|
||||
type ListNics struct {
|
||||
ForDisplay bool `json:"fordisplay,omitempty" doc:"list resources by display flag; only ROOT admin is eligible to pass this parameter"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
NetworkID *UUID `json:"networkid,omitempty" doc:"list nic of the specific vm's network"`
|
||||
NicID *UUID `json:"nicid,omitempty" doc:"the ID of the nic to to list IPs"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid" doc:"the ID of the vm"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"the ID of the vm"`
|
||||
_ bool `name:"listNics" description:"list the vm nics IP to NIC"`
|
||||
}
|
||||
|
||||
|
@ -72,29 +68,6 @@ type ListNicsResponse struct {
|
|||
Nic []Nic `json:"nic"`
|
||||
}
|
||||
|
||||
func (ListNics) response() interface{} {
|
||||
return new(ListNicsResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (ls *ListNics) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListNics) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListNics) each(resp interface{}, callback IterateItemFunc) {
|
||||
nics := resp.(*ListNicsResponse)
|
||||
for i := range nics.Nic {
|
||||
if !callback(&(nics.Nic[i]), nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddIPToNic (Async) represents the assignation of a secondary IP
|
||||
type AddIPToNic struct {
|
||||
NicID *UUID `json:"nicid" doc:"the ID of the nic to which you want to assign private IP"`
|
||||
|
@ -102,11 +75,13 @@ type AddIPToNic struct {
|
|||
_ bool `name:"addIpToNic" description:"Assigns secondary IP to NIC"`
|
||||
}
|
||||
|
||||
func (AddIPToNic) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (AddIPToNic) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (AddIPToNic) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (AddIPToNic) AsyncResponse() interface{} {
|
||||
return new(NicSecondaryIP)
|
||||
}
|
||||
|
||||
|
@ -116,12 +91,14 @@ type RemoveIPFromNic struct {
|
|||
_ bool `name:"removeIpFromNic" description:"Removes secondary IP from the NIC."`
|
||||
}
|
||||
|
||||
func (RemoveIPFromNic) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RemoveIPFromNic) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (RemoveIPFromNic) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (RemoveIPFromNic) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// ActivateIP6 (Async) activates the IP6 on the given NIC
|
||||
|
@ -132,10 +109,12 @@ type ActivateIP6 struct {
|
|||
_ bool `name:"activateIp6" description:"Activate the IPv6 on the VM's nic"`
|
||||
}
|
||||
|
||||
func (ActivateIP6) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (ActivateIP6) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (ActivateIP6) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (ActivateIP6) AsyncResponse() interface{} {
|
||||
return new(Nic)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/nics_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/nics_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListNics) Response() interface{} {
|
||||
return new(ListNicsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListNics) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListNics) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListNics) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListNics) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListNicsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListNicsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.Nic {
|
||||
if !callback(&items.Nic[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
43
vendor/github.com/exoscale/egoscale/oscategories_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/oscategories_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListOSCategories) Response() interface{} {
|
||||
return new(ListOSCategoriesResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListOSCategories) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListOSCategories) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListOSCategories) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListOSCategories) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListOSCategoriesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListOSCategoriesResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.OSCategory {
|
||||
if !callback(&items.OSCategory[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
43
vendor/github.com/exoscale/egoscale/publicipaddresses_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/publicipaddresses_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListPublicIPAddresses) Response() interface{} {
|
||||
return new(ListPublicIPAddressesResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListPublicIPAddresses) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListPublicIPAddresses) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListPublicIPAddresses) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListPublicIPAddresses) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListPublicIPAddressesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListPublicIPAddressesResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.PublicIPAddress {
|
||||
if !callback(&items.PublicIPAddress[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
41
vendor/github.com/exoscale/egoscale/request.go
generated
vendored
41
vendor/github.com/exoscale/egoscale/request.go
generated
vendored
|
@ -24,7 +24,7 @@ func (e ErrorResponse) Error() string {
|
|||
}
|
||||
|
||||
// Error formats a CloudStack job response into a standard error
|
||||
func (e booleanResponse) Error() error {
|
||||
func (e BooleanResponse) Error() error {
|
||||
if !e.Success {
|
||||
return fmt.Errorf("API error: %s", e.DisplayText)
|
||||
}
|
||||
|
@ -32,12 +32,17 @@ func (e booleanResponse) Error() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// XXX: addIpToNic, activateIp6, restorevmresponse are kind of special
|
||||
var responseKeys = map[string]string{
|
||||
func responseKey(key string) (string, bool) {
|
||||
// XXX: addIpToNic, activateIp6, restorevmresponse are kind of special
|
||||
var responseKeys = map[string]string{
|
||||
"addiptonicresponse": "addiptovmnicresponse",
|
||||
"activateip6response": "activateip6nicresponse",
|
||||
"restorevirtualmachineresponse": "restorevmresponse",
|
||||
"updatevmaffinitygroupresponse": "updatevirtualmachineresponse",
|
||||
}
|
||||
|
||||
k, ok := responseKeys[key]
|
||||
return k, ok
|
||||
}
|
||||
|
||||
func (client *Client) parseResponse(resp *http.Response, apiName string) (json.RawMessage, error) {
|
||||
|
@ -60,7 +65,7 @@ func (client *Client) parseResponse(resp *http.Response, apiName string) (json.R
|
|||
|
||||
if !ok {
|
||||
// try again with the special keys
|
||||
value, ok := responseKeys[key]
|
||||
value, ok := responseKey(key)
|
||||
if ok {
|
||||
key = value
|
||||
}
|
||||
|
@ -68,9 +73,7 @@ func (client *Client) parseResponse(resp *http.Response, apiName string) (json.R
|
|||
response, ok = m[key]
|
||||
|
||||
if !ok {
|
||||
for k := range m {
|
||||
return nil, fmt.Errorf("malformed JSON response, %q was expected, got %q", key, k)
|
||||
}
|
||||
return nil, fmt.Errorf("malformed JSON response %d, %q was expected.\n%s", resp.StatusCode, key, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +114,7 @@ func (client *Client) parseResponse(resp *http.Response, apiName string) (json.R
|
|||
func (client *Client) asyncRequest(ctx context.Context, asyncCommand AsyncCommand) (interface{}, error) {
|
||||
var err error
|
||||
|
||||
resp := asyncCommand.asyncResponse()
|
||||
resp := asyncCommand.AsyncResponse()
|
||||
client.AsyncRequestWithContext(
|
||||
ctx,
|
||||
asyncCommand,
|
||||
|
@ -139,8 +142,8 @@ func (client *Client) SyncRequestWithContext(ctx context.Context, command Comman
|
|||
return nil, err
|
||||
}
|
||||
|
||||
response := command.response()
|
||||
b, ok := response.(*booleanResponse)
|
||||
response := command.Response()
|
||||
b, ok := response.(*BooleanResponse)
|
||||
if ok {
|
||||
m := make(map[string]interface{})
|
||||
if errUnmarshal := json.Unmarshal(body, &m); errUnmarshal != nil {
|
||||
|
@ -178,7 +181,7 @@ func (client *Client) BooleanRequest(command Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if b, ok := resp.(*booleanResponse); ok {
|
||||
if b, ok := resp.(*BooleanResponse); ok {
|
||||
return b.Error()
|
||||
}
|
||||
|
||||
|
@ -192,7 +195,7 @@ func (client *Client) BooleanRequestWithContext(ctx context.Context, command Com
|
|||
return err
|
||||
}
|
||||
|
||||
if b, ok := resp.(*booleanResponse); ok {
|
||||
if b, ok := resp.(*BooleanResponse); ok {
|
||||
return b.Error()
|
||||
}
|
||||
|
||||
|
@ -209,9 +212,9 @@ func (client *Client) Request(command Command) (interface{}, error) {
|
|||
|
||||
// RequestWithContext preforms a command with a context
|
||||
func (client *Client) RequestWithContext(ctx context.Context, command Command) (interface{}, error) {
|
||||
switch command.(type) {
|
||||
switch c := command.(type) {
|
||||
case AsyncCommand:
|
||||
return client.asyncRequest(ctx, command.(AsyncCommand))
|
||||
return client.asyncRequest(ctx, c)
|
||||
default:
|
||||
return client.SyncRequestWithContext(ctx, command)
|
||||
}
|
||||
|
@ -278,10 +281,9 @@ func (client *Client) AsyncRequestWithContext(ctx context.Context, asyncCommand
|
|||
|
||||
// Payload builds the HTTP request params from the given command
|
||||
func (client *Client) Payload(command Command) (url.Values, error) {
|
||||
params := url.Values{}
|
||||
err := prepareValues("", params, command)
|
||||
params, err := prepareValues("", command)
|
||||
if err != nil {
|
||||
return params, err
|
||||
return nil, err
|
||||
}
|
||||
if hookReq, ok := command.(onBeforeHook); ok {
|
||||
if err := hookReq.onBeforeSend(params); err != nil {
|
||||
|
@ -292,6 +294,11 @@ func (client *Client) Payload(command Command) (url.Values, error) {
|
|||
params.Set("command", client.APIName(command))
|
||||
params.Set("response", "json")
|
||||
|
||||
if params.Get("expires") == "" && client.Expiration >= 0 {
|
||||
params.Set("signatureversion", "3")
|
||||
params.Set("expires", time.Now().Add(client.Expiration).Local().Format("2006-01-02T15:04:05-0700"))
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
|
|
24
vendor/github.com/exoscale/egoscale/request_type.go
generated
vendored
24
vendor/github.com/exoscale/egoscale/request_type.go
generated
vendored
|
@ -4,27 +4,27 @@ import (
|
|||
"net/url"
|
||||
)
|
||||
|
||||
// Command represents a CloudStack request
|
||||
// Command represents a generic request
|
||||
type Command interface {
|
||||
response() interface{}
|
||||
Response() interface{}
|
||||
}
|
||||
|
||||
// AsyncCommand represents a async CloudStack request
|
||||
// AsyncCommand represents a async request
|
||||
type AsyncCommand interface {
|
||||
Command
|
||||
// Response interface to Unmarshal the JSON into
|
||||
asyncResponse() interface{}
|
||||
AsyncResponse() interface{}
|
||||
}
|
||||
|
||||
// ListCommand represents a CloudStack list request
|
||||
// ListCommand represents a listing request
|
||||
type ListCommand interface {
|
||||
Listable
|
||||
Command
|
||||
// SetPage defines the current pages
|
||||
SetPage(int)
|
||||
// SetPageSize defines the size of the page
|
||||
SetPageSize(int)
|
||||
// each reads the data from the response and feeds channels, and returns true if we are on the last page
|
||||
each(interface{}, IterateItemFunc)
|
||||
// Each reads the data from the response and feeds channels, and returns true if we are on the last page
|
||||
Each(interface{}, IterateItemFunc)
|
||||
}
|
||||
|
||||
// onBeforeHook represents an action to be done on the params before sending them
|
||||
|
@ -57,7 +57,7 @@ const (
|
|||
|
||||
// ErrorCode represents the CloudStack ApiErrorCode enum
|
||||
//
|
||||
// See: https://github.com/apache/cloudstack/blob/master/api/src/org/apache/cloudstack/api/ApiErrorCode.java
|
||||
// See: https://github.com/apache/cloudstack/blob/master/api/src/main/java/org/apache/cloudstack/api/ApiErrorCode.java
|
||||
type ErrorCode int
|
||||
|
||||
//go:generate stringer -type ErrorCode
|
||||
|
@ -162,7 +162,7 @@ const (
|
|||
ServerAPIException CSErrorCode = 9999
|
||||
)
|
||||
|
||||
// ErrorResponse represents the standard error response from CloudStack
|
||||
// ErrorResponse represents the standard error response
|
||||
type ErrorResponse struct {
|
||||
CSErrorCode CSErrorCode `json:"cserrorcode"`
|
||||
ErrorCode ErrorCode `json:"errorcode"`
|
||||
|
@ -177,8 +177,8 @@ type UUIDItem struct {
|
|||
UUID string `json:"uuid"`
|
||||
}
|
||||
|
||||
// booleanResponse represents a boolean response (usually after a deletion)
|
||||
type booleanResponse struct {
|
||||
// BooleanResponse represents a boolean response (usually after a deletion)
|
||||
type BooleanResponse struct {
|
||||
DisplayText string `json:"displaytext,omitempty"`
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
|
|
100
vendor/github.com/exoscale/egoscale/resource_limits.go
generated
vendored
Normal file
100
vendor/github.com/exoscale/egoscale/resource_limits.go
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
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 ResourceTypeName = "public_ip"
|
||||
// VolumeTypeName is the resource type name of a volume
|
||||
VolumeTypeName ResourceTypeName = "volume"
|
||||
// SnapshotTypeName is the resource type name of a snapshot
|
||||
SnapshotTypeName ResourceTypeName = "snapshot"
|
||||
// TemplateTypeName is the resource type name of a template
|
||||
TemplateTypeName ResourceTypeName = "template"
|
||||
// ProjectTypeName is the resource type name of a project
|
||||
ProjectTypeName ResourceTypeName = "project"
|
||||
// NetworkTypeName is the resource type name of a network
|
||||
NetworkTypeName ResourceTypeName = "network"
|
||||
// VPCTypeName is the resource type name of a VPC
|
||||
VPCTypeName ResourceTypeName = "vpc"
|
||||
// CPUTypeName is the resource type name of a CPU
|
||||
CPUTypeName ResourceTypeName = "cpu"
|
||||
// MemoryTypeName is the resource type name of Memory
|
||||
MemoryTypeName ResourceTypeName = "memory"
|
||||
// PrimaryStorageTypeName is the resource type name of primary storage
|
||||
PrimaryStorageTypeName ResourceTypeName = "primary_storage"
|
||||
// SecondaryStorageTypeName is the resource type name of secondary storage
|
||||
SecondaryStorageTypeName ResourceTypeName = "secondary_storage"
|
||||
)
|
||||
|
||||
// ResourceType represents the ID of a resource type (for limits)
|
||||
type ResourceType string
|
||||
|
||||
const (
|
||||
// VirtualMachineType is the resource type ID of a VM
|
||||
VirtualMachineType ResourceType = "0"
|
||||
// IPAddressType is the resource type ID of an IP address
|
||||
IPAddressType ResourceType = "1"
|
||||
// VolumeType is the resource type ID of a volume
|
||||
VolumeType ResourceType = "2"
|
||||
// SnapshotType is the resource type ID of a snapshot
|
||||
SnapshotType ResourceType = "3"
|
||||
// TemplateType is the resource type ID of a template
|
||||
TemplateType ResourceType = "4"
|
||||
// ProjectType is the resource type ID of a project
|
||||
ProjectType ResourceType = "5"
|
||||
// NetworkType is the resource type ID of a network
|
||||
NetworkType ResourceType = "6"
|
||||
// VPCType is the resource type ID of a VPC
|
||||
VPCType ResourceType = "7"
|
||||
// CPUType is the resource type ID of a CPU
|
||||
CPUType ResourceType = "8"
|
||||
// MemoryType is the resource type ID of Memory
|
||||
MemoryType ResourceType = "9"
|
||||
// PrimaryStorageType is the resource type ID of primary storage
|
||||
PrimaryStorageType ResourceType = "10"
|
||||
// SecondaryStorageType is the resource type ID of secondary storage
|
||||
SecondaryStorageType ResourceType = "11"
|
||||
)
|
||||
|
||||
// ResourceLimit represents the limit on a particular resource
|
||||
type ResourceLimit struct {
|
||||
Max int64 `json:"max,omitempty" doc:"the maximum number of the resource. A -1 means the resource currently has no limit."`
|
||||
ResourceType ResourceType `json:"resourcetype,omitempty" doc:"resource type. Values include 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11. See the resourceType parameter for more information on these values."`
|
||||
ResourceTypeName string `json:"resourcetypename,omitempty" doc:"resource type name. Values include user_vm, public_ip, volume, snapshot, template, network, cpu, memory, primary_storage, secondary_storage."`
|
||||
}
|
||||
|
||||
// ListRequest builds the ListResourceLimits request
|
||||
func (limit ResourceLimit) ListRequest() (ListCommand, error) {
|
||||
req := &ListResourceLimits{
|
||||
ResourceType: limit.ResourceType,
|
||||
ResourceTypeName: limit.ResourceTypeName,
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListResourceLimits
|
||||
|
||||
// ListResourceLimits lists the resource limits
|
||||
type ListResourceLimits struct {
|
||||
ID int64 `json:"id,omitempty" doc:"Lists resource limits by ID."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
ResourceType ResourceType `json:"resourcetype,omitempty" doc:"Type of resource. Values are 0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12, and 13. 0 - Instance. Number of instances a user can create. 1 - IP. Number of public IP addresses an account can own. 2 - Volume. Number of disk volumes an account can own. 3 - Snapshot. Number of snapshots an account can own. 4 - Template. Number of templates an account can register/create. 6 - Network. Number of networks an account can own. 8 - CPU. Number of CPU an account can allocate for his resources. 9 - Memory. Amount of RAM an account can allocate for his resources. 10 - PrimaryStorage. Total primary storage space (in GiB) a user can use. 11 - SecondaryStorage. Total secondary storage space (in GiB) a user can use. 12 - Elastic IP. Number of public elastic IP addresses an account can own. 13 - SMTP. If the account is allowed SMTP outbound traffic."`
|
||||
ResourceTypeName string `json:"resourcetypename,omitempty" doc:"Type of resource (wins over resourceType if both are provided). Values are: user_vm - Instance. Number of instances a user can create. public_ip - IP. Number of public IP addresses an account can own. volume - Volume. Number of disk volumes an account can own. snapshot - Snapshot. Number of snapshots an account can own. template - Template. Number of templates an account can register/create. network - Network. Number of networks an account can own. cpu - CPU. Number of CPU an account can allocate for his resources. memory - Memory. Amount of RAM an account can allocate for his resources. primary_storage - PrimaryStorage. Total primary storage space (in GiB) a user can use. secondary_storage - SecondaryStorage. Total secondary storage space (in GiB) a user can use. public_elastic_ip - IP. Number of public elastic IP addresses an account can own. smtp - SG. If the account is allowed SMTP outbound traffic."`
|
||||
|
||||
_ bool `name:"listResourceLimits" description:"Lists resource limits."`
|
||||
}
|
||||
|
||||
// ListResourceLimitsResponse represents a list of resource limits
|
||||
type ListResourceLimitsResponse struct {
|
||||
Count int `json:"count"`
|
||||
ResourceLimit []ResourceLimit `json:"resourcelimit"`
|
||||
}
|
37
vendor/github.com/exoscale/egoscale/resource_metadata.go
generated
vendored
37
vendor/github.com/exoscale/egoscale/resource_metadata.go
generated
vendored
|
@ -1,19 +1,36 @@
|
|||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ResourceDetail represents extra details
|
||||
type ResourceDetail ResourceTag
|
||||
|
||||
// ListRequest builds the ListResourceDetails request
|
||||
func (detail ResourceDetail) ListRequest() (ListCommand, error) {
|
||||
if detail.ResourceType == "" {
|
||||
return nil, fmt.Errorf("the resourcetype parameter is required")
|
||||
}
|
||||
|
||||
req := &ListResourceDetails{
|
||||
ResourceType: detail.ResourceType,
|
||||
ResourceID: detail.ResourceID,
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListResourceDetails
|
||||
|
||||
// ListResourceDetails lists the resource tag(s) (but different from listTags...)
|
||||
type ListResourceDetails struct {
|
||||
ResourceType string `json:"resourcetype" doc:"list by resource type"`
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ForDisplay bool `json:"fordisplay,omitempty" doc:"if set to true, only details marked with display=true, are returned. False by default"`
|
||||
Key string `json:"key,omitempty" doc:"list by key"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
ResourceID *UUID `json:"resourceid,omitempty" doc:"list by resource id"`
|
||||
Value string `json:"value,omitempty" doc:"list by key, value. Needs to be passed only along with key"`
|
||||
IsRecursive bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
_ bool `name:"listResourceDetails" description:"List resource detail(s)"`
|
||||
}
|
||||
|
||||
|
@ -22,15 +39,3 @@ type ListResourceDetailsResponse struct {
|
|||
Count int `json:"count"`
|
||||
ResourceDetail []ResourceTag `json:"resourcedetail"`
|
||||
}
|
||||
|
||||
func (*ListResourceDetails) name() string {
|
||||
return "listResourceDetails"
|
||||
}
|
||||
|
||||
func (*ListResourceDetails) description() string {
|
||||
return "List resource detail(s)"
|
||||
}
|
||||
|
||||
func (*ListResourceDetails) response() interface{} {
|
||||
return new(ListResourceDetailsResponse)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/resourcedetails_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/resourcedetails_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListResourceDetails) Response() interface{} {
|
||||
return new(ListResourceDetailsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListResourceDetails) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListResourceDetails) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListResourceDetails) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListResourceDetails) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListResourceDetailsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListResourceDetailsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.ResourceDetail {
|
||||
if !callback(&items.ResourceDetail[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
43
vendor/github.com/exoscale/egoscale/resourcelimits_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/resourcelimits_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListResourceLimits) Response() interface{} {
|
||||
return new(ListResourceLimitsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListResourceLimits) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListResourceLimits) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListResourceLimits) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListResourceLimits) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListResourceLimitsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListResourceLimitsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.ResourceLimit {
|
||||
if !callback(&items.ResourceLimit[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
22
vendor/github.com/exoscale/egoscale/reversedns.go
generated
vendored
22
vendor/github.com/exoscale/egoscale/reversedns.go
generated
vendored
|
@ -20,8 +20,9 @@ type DeleteReverseDNSFromPublicIPAddress struct {
|
|||
_ bool `name:"deleteReverseDnsFromPublicIpAddress" description:"delete the PTR DNS record from the public IP address"`
|
||||
}
|
||||
|
||||
func (*DeleteReverseDNSFromPublicIPAddress) response() interface{} {
|
||||
return new(booleanResponse)
|
||||
// Response returns the struct to unmarshal
|
||||
func (*DeleteReverseDNSFromPublicIPAddress) Response() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// DeleteReverseDNSFromVirtualMachine is a command to create/delete the PTR record(s) of a virtual machine
|
||||
|
@ -30,8 +31,9 @@ type DeleteReverseDNSFromVirtualMachine struct {
|
|||
_ bool `name:"deleteReverseDnsFromVirtualMachine" description:"Delete the PTR DNS record(s) from the virtual machine"`
|
||||
}
|
||||
|
||||
func (*DeleteReverseDNSFromVirtualMachine) response() interface{} {
|
||||
return new(booleanResponse)
|
||||
// Response returns the struct to unmarshal
|
||||
func (*DeleteReverseDNSFromVirtualMachine) Response() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// QueryReverseDNSForPublicIPAddress is a command to create/query the PTR record of a public IP address
|
||||
|
@ -40,7 +42,8 @@ type QueryReverseDNSForPublicIPAddress struct {
|
|||
_ bool `name:"queryReverseDnsForPublicIpAddress" description:"Query the PTR DNS record for the public IP address"`
|
||||
}
|
||||
|
||||
func (*QueryReverseDNSForPublicIPAddress) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (*QueryReverseDNSForPublicIPAddress) Response() interface{} {
|
||||
return new(IPAddress)
|
||||
}
|
||||
|
||||
|
@ -50,7 +53,8 @@ type QueryReverseDNSForVirtualMachine struct {
|
|||
_ bool `name:"queryReverseDnsForVirtualMachine" description:"Query the PTR DNS record(s) for the virtual machine"`
|
||||
}
|
||||
|
||||
func (*QueryReverseDNSForVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (*QueryReverseDNSForVirtualMachine) Response() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -61,7 +65,8 @@ type UpdateReverseDNSForPublicIPAddress struct {
|
|||
_ bool `name:"updateReverseDnsForPublicIpAddress" description:"Update/create the PTR DNS record for the public IP address"`
|
||||
}
|
||||
|
||||
func (*UpdateReverseDNSForPublicIPAddress) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (*UpdateReverseDNSForPublicIPAddress) Response() interface{} {
|
||||
return new(IPAddress)
|
||||
}
|
||||
|
||||
|
@ -72,6 +77,7 @@ type UpdateReverseDNSForVirtualMachine struct {
|
|||
_ bool `name:"updateReverseDnsForVirtualMachine" description:"Update/create the PTR DNS record(s) for the virtual machine"`
|
||||
}
|
||||
|
||||
func (*UpdateReverseDNSForVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (*UpdateReverseDNSForVirtualMachine) Response() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
|
264
vendor/github.com/exoscale/egoscale/runstatus.go
generated
vendored
Normal file
264
vendor/github.com/exoscale/egoscale/runstatus.go
generated
vendored
Normal file
|
@ -0,0 +1,264 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RunstatusValidationErrorResponse represents an error in the API
|
||||
type RunstatusValidationErrorResponse map[string][]string
|
||||
|
||||
// RunstatusErrorResponse represents the default errors
|
||||
type RunstatusErrorResponse struct {
|
||||
Detail string `json:"detail"`
|
||||
}
|
||||
|
||||
// runstatusPagesURL is the only URL that cannot be guessed
|
||||
const runstatusPagesURL = "/pages"
|
||||
|
||||
// RunstatusPage runstatus page
|
||||
type RunstatusPage struct {
|
||||
Created *time.Time `json:"created,omitempty"`
|
||||
DarkTheme bool `json:"dark_theme,omitempty"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
GradientEnd string `json:"gradient_end,omitempty"`
|
||||
GradientStart string `json:"gradient_start,omitempty"`
|
||||
HeaderBackground string `json:"header_background,omitempty"`
|
||||
ID int `json:"id,omitempty"`
|
||||
Incidents []RunstatusIncident `json:"incidents,omitempty"`
|
||||
IncidentsURL string `json:"incidents_url,omitempty"`
|
||||
Logo string `json:"logo,omitempty"`
|
||||
Maintenances []RunstatusMaintenance `json:"maintenances,omitempty"`
|
||||
MaintenancesURL string `json:"maintenances_url,omitempty"`
|
||||
Name string `json:"name"` //fake field (used to post a new runstatus page)
|
||||
OkText string `json:"ok_text,omitempty"`
|
||||
Plan string `json:"plan,omitempty"`
|
||||
PublicURL string `json:"public_url,omitempty"`
|
||||
Services []RunstatusService `json:"services,omitempty"`
|
||||
ServicesURL string `json:"services_url,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Subdomain string `json:"subdomain"`
|
||||
SupportEmail string `json:"support_email,omitempty"`
|
||||
TimeZone string `json:"time_zone,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
TitleColor string `json:"title_color,omitempty"`
|
||||
TwitterUsername string `json:"twitter_username,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// Match returns true if the other page has got similarities with itself
|
||||
func (page RunstatusPage) Match(other RunstatusPage) bool {
|
||||
if other.Subdomain != "" && page.Subdomain == other.Subdomain {
|
||||
return true
|
||||
}
|
||||
|
||||
if other.ID > 0 && page.ID == other.ID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
//RunstatusPageList runstatus page list
|
||||
type RunstatusPageList struct {
|
||||
Count int `json:"count"`
|
||||
Next string `json:"next"`
|
||||
Previous string `json:"previous"`
|
||||
Results []RunstatusPage `json:"results"`
|
||||
}
|
||||
|
||||
// CreateRunstatusPage create runstatus page
|
||||
func (client *Client) CreateRunstatusPage(ctx context.Context, page RunstatusPage) (*RunstatusPage, error) {
|
||||
resp, err := client.runstatusRequest(ctx, client.Endpoint+runstatusPagesURL, page, "POST")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var p *RunstatusPage
|
||||
if err := json.Unmarshal(resp, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// DeleteRunstatusPage delete runstatus page
|
||||
func (client *Client) DeleteRunstatusPage(ctx context.Context, page RunstatusPage) error {
|
||||
if page.URL == "" {
|
||||
return fmt.Errorf("empty URL for %#v", page)
|
||||
}
|
||||
_, err := client.runstatusRequest(ctx, page.URL, nil, "DELETE")
|
||||
return err
|
||||
}
|
||||
|
||||
// GetRunstatusPage fetches the runstatus page
|
||||
func (client *Client) GetRunstatusPage(ctx context.Context, page RunstatusPage) (*RunstatusPage, error) {
|
||||
if page.URL != "" {
|
||||
return client.getRunstatusPage(ctx, page.URL)
|
||||
}
|
||||
|
||||
ps, err := client.ListRunstatusPages(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range ps {
|
||||
if ps[i].Match(page) {
|
||||
return &ps[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%#v not found", page)
|
||||
}
|
||||
|
||||
func (client *Client) getRunstatusPage(ctx context.Context, pageURL string) (*RunstatusPage, error) {
|
||||
resp, err := client.runstatusRequest(ctx, pageURL, nil, "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p := new(RunstatusPage)
|
||||
if err := json.Unmarshal(resp, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// NOTE: fix the missing IDs
|
||||
for i := range p.Maintenances {
|
||||
if err := p.Maintenances[i].FakeID(); err != nil {
|
||||
log.Printf("bad fake ID for %#v, %s", p.Maintenances[i], err)
|
||||
}
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// ListRunstatusPages list all the runstatus pages
|
||||
func (client *Client) ListRunstatusPages(ctx context.Context) ([]RunstatusPage, error) {
|
||||
resp, err := client.runstatusRequest(ctx, client.Endpoint+runstatusPagesURL, nil, "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var p *RunstatusPageList
|
||||
if err := json.Unmarshal(resp, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// XXX: handle pagination
|
||||
return p.Results, nil
|
||||
}
|
||||
|
||||
// Error formats the DNSerror into a string
|
||||
func (req RunstatusErrorResponse) Error() string {
|
||||
return fmt.Sprintf("Runstatus error: %s", req.Detail)
|
||||
}
|
||||
|
||||
// Error formats the DNSerror into a string
|
||||
func (req RunstatusValidationErrorResponse) Error() string {
|
||||
if len(req) > 0 {
|
||||
errs := []string{}
|
||||
for name, ss := range req {
|
||||
if len(ss) > 0 {
|
||||
errs = append(errs, fmt.Sprintf("%s: %s", name, strings.Join(ss, ", ")))
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("Runstatus error: %s", strings.Join(errs, "; "))
|
||||
}
|
||||
return fmt.Sprintf("Runstatus error")
|
||||
}
|
||||
|
||||
func (client *Client) runstatusRequest(ctx context.Context, uri string, structParam interface{}, method string) (json.RawMessage, error) {
|
||||
reqURL, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if reqURL.Scheme == "" {
|
||||
return nil, fmt.Errorf("only absolute URI are considered valid, got %q", uri)
|
||||
}
|
||||
|
||||
var params string
|
||||
if structParam != nil {
|
||||
m, err := json.Marshal(structParam)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
params = string(m)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, reqURL.String(), strings.NewReader(params))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
time := time.Now().Local().Format("2006-01-02T15:04:05-0700")
|
||||
|
||||
payload := fmt.Sprintf("%s%s%s", req.URL.String(), time, params)
|
||||
|
||||
mac := hmac.New(sha256.New, []byte(client.apiSecret))
|
||||
_, err = mac.Write([]byte(payload))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signature := hex.EncodeToString(mac.Sum(nil))
|
||||
|
||||
var hdr = make(http.Header)
|
||||
|
||||
hdr.Add("Authorization", fmt.Sprintf("Exoscale-HMAC-SHA256 %s:%s", client.APIKey, signature))
|
||||
hdr.Add("Exoscale-Date", time)
|
||||
hdr.Add("User-Agent", fmt.Sprintf("exoscale/egoscale (%v)", Version))
|
||||
hdr.Add("Accept", "application/json")
|
||||
if params != "" {
|
||||
hdr.Add("Content-Type", "application/json")
|
||||
}
|
||||
req.Header = hdr
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
resp, err := client.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close() // nolint: errcheck
|
||||
|
||||
if resp.StatusCode == 204 {
|
||||
if method != "DELETE" {
|
||||
return nil, fmt.Errorf("only DELETE is expected to produce 204, was %q", method)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
contentType := resp.Header.Get("content-type")
|
||||
if !strings.Contains(contentType, "application/json") {
|
||||
return nil, fmt.Errorf(`response content-type expected to be "application/json", got %q`, contentType)
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode >= 400 {
|
||||
rerr := new(RunstatusValidationErrorResponse)
|
||||
if err := json.Unmarshal(b, rerr); err == nil {
|
||||
return nil, rerr
|
||||
}
|
||||
rverr := new(RunstatusErrorResponse)
|
||||
if err := json.Unmarshal(b, rverr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, rverr
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
37
vendor/github.com/exoscale/egoscale/runstatus_event.go
generated
vendored
Normal file
37
vendor/github.com/exoscale/egoscale/runstatus_event.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
//RunstatusEvent is a runstatus event
|
||||
type RunstatusEvent struct {
|
||||
Created *time.Time `json:"created,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
// UpdateRunstatusIncident create runstatus incident event
|
||||
// Events can be updates or final message with status completed.
|
||||
func (client *Client) UpdateRunstatusIncident(ctx context.Context, incident RunstatusIncident, event RunstatusEvent) error {
|
||||
if incident.EventsURL == "" {
|
||||
return fmt.Errorf("empty Events URL for %#v", incident)
|
||||
}
|
||||
|
||||
_, err := client.runstatusRequest(ctx, incident.EventsURL, event, "POST")
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateRunstatusMaintenance adds a event to a maintenance.
|
||||
// Events can be updates or final message with status completed.
|
||||
func (client *Client) UpdateRunstatusMaintenance(ctx context.Context, maintenance RunstatusMaintenance, event RunstatusEvent) error {
|
||||
if maintenance.EventsURL == "" {
|
||||
return fmt.Errorf("empty Events URL for %#v", maintenance)
|
||||
}
|
||||
|
||||
_, err := client.runstatusRequest(ctx, maintenance.EventsURL, event, "POST")
|
||||
return err
|
||||
}
|
144
vendor/github.com/exoscale/egoscale/runstatus_incident.go
generated
vendored
Normal file
144
vendor/github.com/exoscale/egoscale/runstatus_incident.go
generated
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
//RunstatusIncident is a runstatus incident
|
||||
type RunstatusIncident struct {
|
||||
EndDate *time.Time `json:"end_date,omitempty"`
|
||||
Events []RunstatusEvent `json:"events,omitempty"`
|
||||
EventsURL string `json:"events_url,omitempty"`
|
||||
ID int `json:"id,omitempty"`
|
||||
PageURL string `json:"page_url,omitempty"` // fake field
|
||||
PostMortem string `json:"post_mortem,omitempty"`
|
||||
RealTime bool `json:"real_time,omitempty"`
|
||||
Services []string `json:"services"`
|
||||
StartDate *time.Time `json:"start_date,omitempty"`
|
||||
State string `json:"state"`
|
||||
Status string `json:"status"`
|
||||
StatusText string `json:"status_text"`
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// Match returns true if the other incident has got similarities with itself
|
||||
func (incident RunstatusIncident) Match(other RunstatusIncident) bool {
|
||||
if other.Title != "" && incident.Title == other.Title {
|
||||
return true
|
||||
}
|
||||
|
||||
if other.ID > 0 && incident.ID == other.ID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
//RunstatusIncidentList is a list of incident
|
||||
type RunstatusIncidentList struct {
|
||||
Incidents []RunstatusIncident `json:"incidents"`
|
||||
}
|
||||
|
||||
// GetRunstatusIncident retrieves the details of a specific incident.
|
||||
func (client *Client) GetRunstatusIncident(ctx context.Context, incident RunstatusIncident) (*RunstatusIncident, error) {
|
||||
if incident.URL != "" {
|
||||
return client.getRunstatusIncident(ctx, incident.URL)
|
||||
}
|
||||
|
||||
if incident.PageURL == "" {
|
||||
return nil, fmt.Errorf("empty Page URL for %#v", incident)
|
||||
}
|
||||
|
||||
page, err := client.getRunstatusPage(ctx, incident.PageURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
is, err := client.ListRunstatusIncidents(ctx, *page)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range is {
|
||||
if is[i].Match(incident) {
|
||||
return &is[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%#v not found", incident)
|
||||
}
|
||||
|
||||
func (client *Client) getRunstatusIncident(ctx context.Context, incidentURL string) (*RunstatusIncident, error) {
|
||||
resp, err := client.runstatusRequest(ctx, incidentURL, nil, "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i := new(RunstatusIncident)
|
||||
if err := json.Unmarshal(resp, i); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// ListRunstatusIncidents lists the incidents for a specific page.
|
||||
func (client *Client) ListRunstatusIncidents(ctx context.Context, page RunstatusPage) ([]RunstatusIncident, error) {
|
||||
if page.IncidentsURL == "" {
|
||||
return nil, fmt.Errorf("empty Incidents URL for %#v", page)
|
||||
}
|
||||
|
||||
resp, err := client.runstatusRequest(ctx, page.IncidentsURL, nil, "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var p *RunstatusIncidentList
|
||||
if err := json.Unmarshal(resp, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// NOTE: no pagination
|
||||
return p.Incidents, nil
|
||||
}
|
||||
|
||||
// CreateRunstatusIncident create runstatus incident
|
||||
func (client *Client) CreateRunstatusIncident(ctx context.Context, incident RunstatusIncident) (*RunstatusIncident, error) {
|
||||
if incident.PageURL == "" {
|
||||
return nil, fmt.Errorf("empty Page URL for %#v", incident)
|
||||
}
|
||||
|
||||
page, err := client.getRunstatusPage(ctx, incident.PageURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if page.IncidentsURL == "" {
|
||||
return nil, fmt.Errorf("empty Incidents URL for %#v", page)
|
||||
}
|
||||
|
||||
resp, err := client.runstatusRequest(ctx, page.IncidentsURL, incident, "POST")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i := &RunstatusIncident{}
|
||||
if err := json.Unmarshal(resp, &i); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// DeleteRunstatusIncident delete runstatus incident
|
||||
func (client *Client) DeleteRunstatusIncident(ctx context.Context, incident RunstatusIncident) error {
|
||||
if incident.URL == "" {
|
||||
return fmt.Errorf("empty URL for %#v", incident)
|
||||
}
|
||||
|
||||
_, err := client.runstatusRequest(ctx, incident.URL, nil, "DELETE")
|
||||
return err
|
||||
}
|
178
vendor/github.com/exoscale/egoscale/runstatus_maintenance.go
generated
vendored
Normal file
178
vendor/github.com/exoscale/egoscale/runstatus_maintenance.go
generated
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RunstatusMaintenance is a runstatus maintenance
|
||||
type RunstatusMaintenance struct {
|
||||
Created *time.Time `json:"created,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
EndDate *time.Time `json:"end_date"`
|
||||
Events []RunstatusEvent `json:"events,omitempty"`
|
||||
EventsURL string `json:"events_url,omitempty"`
|
||||
ID int `json:"id,omitempty"` // missing field
|
||||
PageURL string `json:"page_url,omitempty"` // fake field
|
||||
RealTime bool `json:"real_time,omitempty"`
|
||||
Services []string `json:"services"`
|
||||
StartDate *time.Time `json:"start_date"`
|
||||
Status string `json:"status"`
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// Match returns true if the other maintenance has got similarities with itself
|
||||
func (maintenance RunstatusMaintenance) Match(other RunstatusMaintenance) bool {
|
||||
if other.Title != "" && maintenance.Title == other.Title {
|
||||
return true
|
||||
}
|
||||
|
||||
if other.ID > 0 && maintenance.ID == other.ID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// FakeID fills up the ID field as it's currently missing
|
||||
func (maintenance *RunstatusMaintenance) FakeID() error {
|
||||
if maintenance.ID > 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if maintenance.URL == "" {
|
||||
return fmt.Errorf("empty URL for %#v", maintenance)
|
||||
}
|
||||
|
||||
u, err := url.Parse(maintenance.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s := path.Base(u.Path)
|
||||
id, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
maintenance.ID = id
|
||||
return nil
|
||||
}
|
||||
|
||||
//RunstatusMaintenanceList is a list of incident
|
||||
type RunstatusMaintenanceList struct {
|
||||
Maintenances []RunstatusMaintenance `json:"maintenances"`
|
||||
}
|
||||
|
||||
// GetRunstatusMaintenance retrieves the details of a specific maintenance.
|
||||
func (client *Client) GetRunstatusMaintenance(ctx context.Context, maintenance RunstatusMaintenance) (*RunstatusMaintenance, error) {
|
||||
if maintenance.URL != "" {
|
||||
return client.getRunstatusMaintenance(ctx, maintenance.URL)
|
||||
}
|
||||
|
||||
if maintenance.PageURL == "" {
|
||||
return nil, fmt.Errorf("empty Page URL for %#v", maintenance)
|
||||
}
|
||||
|
||||
page, err := client.getRunstatusPage(ctx, maintenance.PageURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ms, err := client.ListRunstatusMaintenances(ctx, *page)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range ms {
|
||||
if ms[i].Match(maintenance) {
|
||||
return &ms[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%#v not found", maintenance)
|
||||
}
|
||||
|
||||
func (client *Client) getRunstatusMaintenance(ctx context.Context, maintenanceURL string) (*RunstatusMaintenance, error) {
|
||||
resp, err := client.runstatusRequest(ctx, maintenanceURL, nil, "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m := new(RunstatusMaintenance)
|
||||
if err := json.Unmarshal(resp, m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// ListRunstatusMaintenances returns the list of maintenances for the page.
|
||||
func (client *Client) ListRunstatusMaintenances(ctx context.Context, page RunstatusPage) ([]RunstatusMaintenance, error) {
|
||||
if page.MaintenancesURL == "" {
|
||||
return nil, fmt.Errorf("empty Maintenances URL for %#v", page)
|
||||
}
|
||||
|
||||
resp, err := client.runstatusRequest(ctx, page.MaintenancesURL, nil, "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var p *RunstatusMaintenanceList
|
||||
if err := json.Unmarshal(resp, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// NOTE: fix the missing IDs
|
||||
for i := range p.Maintenances {
|
||||
if err := p.Maintenances[i].FakeID(); err != nil {
|
||||
log.Printf("bad fake ID for %#v, %s", p.Maintenances[i], err)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: the list of maintenances doesn't have any pagination
|
||||
return p.Maintenances, nil
|
||||
}
|
||||
|
||||
// CreateRunstatusMaintenance create runstatus Maintenance
|
||||
func (client *Client) CreateRunstatusMaintenance(ctx context.Context, maintenance RunstatusMaintenance) (*RunstatusMaintenance, error) {
|
||||
if maintenance.PageURL == "" {
|
||||
return nil, fmt.Errorf("empty Page URL for %#v", maintenance)
|
||||
}
|
||||
|
||||
page, err := client.getRunstatusPage(ctx, maintenance.PageURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := client.runstatusRequest(ctx, page.MaintenancesURL, maintenance, "POST")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m := &RunstatusMaintenance{}
|
||||
if err := json.Unmarshal(resp, &m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := m.FakeID(); err != nil {
|
||||
log.Printf("bad fake ID for %#v, %s", m, err)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// DeleteRunstatusMaintenance delete runstatus Maintenance
|
||||
func (client *Client) DeleteRunstatusMaintenance(ctx context.Context, maintenance RunstatusMaintenance) error {
|
||||
if maintenance.URL == "" {
|
||||
return fmt.Errorf("empty URL for %#v", maintenance)
|
||||
}
|
||||
|
||||
_, err := client.runstatusRequest(ctx, maintenance.URL, nil, "DELETE")
|
||||
return err
|
||||
}
|
170
vendor/github.com/exoscale/egoscale/runstatus_service.go
generated
vendored
Normal file
170
vendor/github.com/exoscale/egoscale/runstatus_service.go
generated
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// RunstatusService is a runstatus service
|
||||
type RunstatusService struct {
|
||||
ID int `json:"id"` // missing field
|
||||
Name string `json:"name"`
|
||||
PageURL string `json:"page_url,omitempty"` // fake field
|
||||
State string `json:"state,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// FakeID fills up the ID field as it's currently missing
|
||||
func (service *RunstatusService) FakeID() error {
|
||||
if service.ID > 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if service.URL == "" {
|
||||
return fmt.Errorf("empty URL for %#v", service)
|
||||
}
|
||||
|
||||
u, err := url.Parse(service.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s := path.Base(u.Path)
|
||||
id, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
service.ID = id
|
||||
return nil
|
||||
}
|
||||
|
||||
// Match returns true if the other service has got similarities with itself
|
||||
func (service RunstatusService) Match(other RunstatusService) bool {
|
||||
if other.Name != "" && service.Name == other.Name {
|
||||
return true
|
||||
}
|
||||
|
||||
if other.ID > 0 && service.ID == other.ID {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// RunstatusServiceList service list
|
||||
type RunstatusServiceList struct {
|
||||
Services []RunstatusService `json:"services"`
|
||||
}
|
||||
|
||||
// DeleteRunstatusService delete runstatus service
|
||||
func (client *Client) DeleteRunstatusService(ctx context.Context, service RunstatusService) error {
|
||||
if service.URL == "" {
|
||||
return fmt.Errorf("empty URL for %#v", service)
|
||||
}
|
||||
|
||||
_, err := client.runstatusRequest(ctx, service.URL, nil, "DELETE")
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateRunstatusService create runstatus service
|
||||
func (client *Client) CreateRunstatusService(ctx context.Context, service RunstatusService) (*RunstatusService, error) {
|
||||
if service.PageURL == "" {
|
||||
return nil, fmt.Errorf("empty Page URL for %#v", service)
|
||||
}
|
||||
|
||||
page, err := client.GetRunstatusPage(ctx, RunstatusPage{URL: service.PageURL})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := client.runstatusRequest(ctx, page.ServicesURL, service, "POST")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &RunstatusService{}
|
||||
if err := json.Unmarshal(resp, s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// GetRunstatusService displays service detail.
|
||||
func (client *Client) GetRunstatusService(ctx context.Context, service RunstatusService) (*RunstatusService, error) {
|
||||
if service.URL != "" {
|
||||
return client.getRunstatusService(ctx, service.URL)
|
||||
}
|
||||
|
||||
if service.PageURL == "" {
|
||||
return nil, fmt.Errorf("empty Page URL in %#v", service)
|
||||
}
|
||||
|
||||
page, err := client.getRunstatusPage(ctx, service.PageURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ss, err := client.ListRunstatusServices(ctx, *page)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range ss {
|
||||
if ss[i].Match(service) {
|
||||
return &ss[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%#v not found", service)
|
||||
}
|
||||
|
||||
func (client *Client) getRunstatusService(ctx context.Context, serviceURL string) (*RunstatusService, error) {
|
||||
resp, err := client.runstatusRequest(ctx, serviceURL, nil, "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &RunstatusService{}
|
||||
if err := json.Unmarshal(resp, &s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.FakeID(); err != nil {
|
||||
log.Printf("bad fake ID for %#v, %s", s, err)
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// ListRunstatusServices displays the list of services.
|
||||
func (client *Client) ListRunstatusServices(ctx context.Context, page RunstatusPage) ([]RunstatusService, error) {
|
||||
if page.ServicesURL == "" {
|
||||
return nil, fmt.Errorf("empty Services URL for %#v", page)
|
||||
}
|
||||
|
||||
resp, err := client.runstatusRequest(ctx, page.ServicesURL, nil, "GET")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var p *RunstatusServiceList
|
||||
if err := json.Unmarshal(resp, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// NOTE: fix the missing IDs
|
||||
for i := range p.Services {
|
||||
if err := p.Services[i].FakeID(); err != nil {
|
||||
log.Printf("bad fake ID for %#v, %s", p.Services[i], err)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: no pagination
|
||||
return p.Services, nil
|
||||
}
|
103
vendor/github.com/exoscale/egoscale/security_groups.go
generated
vendored
103
vendor/github.com/exoscale/egoscale/security_groups.go
generated
vendored
|
@ -12,10 +12,8 @@ import (
|
|||
type SecurityGroup struct {
|
||||
Account string `json:"account,omitempty" doc:"the account owning the security group"`
|
||||
Description string `json:"description,omitempty" doc:"the description of the security group"`
|
||||
Domain string `json:"domain,omitempty" doc:"the domain name of the security group"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain ID of the security group"`
|
||||
EgressRule []EgressRule `json:"egressrule,omitempty" doc:"the list of egress rules associated with the security group"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the ID of the security group"`
|
||||
ID *UUID `json:"id" doc:"the ID of the security group"`
|
||||
IngressRule []IngressRule `json:"ingressrule,omitempty" doc:"the list of ingress rules associated with the security group"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the security group"`
|
||||
}
|
||||
|
@ -23,7 +21,6 @@ type SecurityGroup struct {
|
|||
// UserSecurityGroup converts a SecurityGroup to a UserSecurityGroup
|
||||
func (sg SecurityGroup) UserSecurityGroup() UserSecurityGroup {
|
||||
return UserSecurityGroup{
|
||||
Account: sg.Account,
|
||||
Group: sg.Name,
|
||||
}
|
||||
}
|
||||
|
@ -31,8 +28,6 @@ func (sg SecurityGroup) UserSecurityGroup() UserSecurityGroup {
|
|||
// ListRequest builds the ListSecurityGroups request
|
||||
func (sg SecurityGroup) ListRequest() (ListCommand, error) {
|
||||
req := &ListSecurityGroups{
|
||||
Account: sg.Account,
|
||||
DomainID: sg.DomainID,
|
||||
ID: sg.ID,
|
||||
SecurityGroupName: sg.Name,
|
||||
}
|
||||
|
@ -46,10 +41,7 @@ func (sg SecurityGroup) Delete(ctx context.Context, client *Client) error {
|
|||
return fmt.Errorf("a SecurityGroup may only be deleted using ID or Name")
|
||||
}
|
||||
|
||||
req := &DeleteSecurityGroup{
|
||||
Account: sg.Account,
|
||||
DomainID: sg.DomainID,
|
||||
}
|
||||
req := &DeleteSecurityGroup{}
|
||||
|
||||
if sg.ID != nil {
|
||||
req.ID = sg.ID
|
||||
|
@ -79,18 +71,15 @@ func (sg SecurityGroup) RuleByID(ruleID UUID) (*IngressRule, *EgressRule) {
|
|||
|
||||
// IngressRule represents the ingress rule
|
||||
type IngressRule struct {
|
||||
Account string `json:"account,omitempty" doc:"account owning the security group rule"`
|
||||
CIDR *CIDR `json:"cidr,omitempty" doc:"the CIDR notation for the base IP address of the security group rule"`
|
||||
Description string `json:"description,omitempty" doc:"description of the security group rule"`
|
||||
EndPort uint16 `json:"endport,omitempty" doc:"the ending port of the security group rule "`
|
||||
IcmpCode uint8 `json:"icmpcode,omitempty" doc:"the code for the ICMP message response"`
|
||||
IcmpType uint8 `json:"icmptype,omitempty" doc:"the type of the ICMP message response"`
|
||||
Protocol string `json:"protocol,omitempty" doc:"the protocol of the security group rule"`
|
||||
RuleID *UUID `json:"ruleid,omitempty" doc:"the id of the security group rule"`
|
||||
SecurityGroupID *UUID `json:"securitygroupid,omitempty"`
|
||||
RuleID *UUID `json:"ruleid" doc:"the id of the security group rule"`
|
||||
SecurityGroupName string `json:"securitygroupname,omitempty" doc:"security group name"`
|
||||
StartPort uint16 `json:"startport,omitempty" doc:"the starting port of the security group rule"`
|
||||
UserSecurityGroupList []UserSecurityGroup `json:"usersecuritygrouplist,omitempty"`
|
||||
}
|
||||
|
||||
// EgressRule represents the ingress rule
|
||||
|
@ -99,7 +88,6 @@ type EgressRule IngressRule
|
|||
// UserSecurityGroup represents the traffic of another security group
|
||||
type UserSecurityGroup struct {
|
||||
Group string `json:"group,omitempty"`
|
||||
Account string `json:"account,omitempty"`
|
||||
}
|
||||
|
||||
// String gives the UserSecurityGroup name
|
||||
|
@ -110,51 +98,49 @@ func (usg UserSecurityGroup) String() string {
|
|||
// CreateSecurityGroup represents a security group creation
|
||||
type CreateSecurityGroup struct {
|
||||
Name string `json:"name" doc:"name of the security group"`
|
||||
Account string `json:"account,omitempty" doc:"an optional account for the security group. Must be used with domainId."`
|
||||
Description string `json:"description,omitempty" doc:"the description of the security group"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"an optional domainId for the security group. If the account parameter is used, domainId must also be used."`
|
||||
_ bool `name:"createSecurityGroup" description:"Creates a security group"`
|
||||
}
|
||||
|
||||
func (CreateSecurityGroup) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (CreateSecurityGroup) Response() interface{} {
|
||||
return new(SecurityGroup)
|
||||
}
|
||||
|
||||
// DeleteSecurityGroup represents a security group deletion
|
||||
type DeleteSecurityGroup struct {
|
||||
Account string `json:"account,omitempty" doc:"the account of the security group. Must be specified with domain ID"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain ID of account owning the security group"`
|
||||
ID *UUID `json:"id,omitempty" doc:"The ID of the security group. Mutually exclusive with name parameter"`
|
||||
Name string `json:"name,omitempty" doc:"The ID of the security group. Mutually exclusive with id parameter"`
|
||||
_ bool `name:"deleteSecurityGroup" description:"Deletes security group"`
|
||||
}
|
||||
|
||||
func (DeleteSecurityGroup) response() interface{} {
|
||||
return new(booleanResponse)
|
||||
// Response returns the struct to unmarshal
|
||||
func (DeleteSecurityGroup) Response() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// AuthorizeSecurityGroupIngress (Async) represents the ingress rule creation
|
||||
type AuthorizeSecurityGroupIngress struct {
|
||||
Account string `json:"account,omitempty" doc:"an optional account for the security group. Must be used with domainId."`
|
||||
CIDRList []CIDR `json:"cidrlist,omitempty" doc:"the cidr list associated"`
|
||||
Description string `json:"description,omitempty" doc:"the description of the ingress/egress rule"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"an optional domainid for the security group. If the account parameter is used, domainid must also be used."`
|
||||
EndPort uint16 `json:"endport,omitempty" doc:"end port for this ingress rule"`
|
||||
EndPort uint16 `json:"endport,omitempty" doc:"end port for this ingress/egress rule"`
|
||||
IcmpCode uint8 `json:"icmpcode,omitempty" doc:"error code for this icmp message"`
|
||||
IcmpType uint8 `json:"icmptype,omitempty" doc:"type of the icmp message being sent"`
|
||||
Protocol string `json:"protocol,omitempty" doc:"TCP is default. UDP, ICMP, ICMPv6, AH, ESP, GRE are the other supported protocols"`
|
||||
Protocol string `json:"protocol,omitempty" doc:"TCP is default. UDP, ICMP, ICMPv6, AH, ESP, GRE, IPIP are the other supported protocols"`
|
||||
SecurityGroupID *UUID `json:"securitygroupid,omitempty" doc:"The ID of the security group. Mutually exclusive with securitygroupname parameter"`
|
||||
SecurityGroupName string `json:"securitygroupname,omitempty" doc:"The name of the security group. Mutually exclusive with securitygroupid parameter"`
|
||||
StartPort uint16 `json:"startport,omitempty" doc:"start port for this ingress rule"`
|
||||
StartPort uint16 `json:"startport,omitempty" doc:"start port for this ingress/egress rule"`
|
||||
UserSecurityGroupList []UserSecurityGroup `json:"usersecuritygrouplist,omitempty" doc:"user to security group mapping"`
|
||||
_ bool `name:"authorizeSecurityGroupIngress" description:"Authorizes a particular ingress/egress rule for this security group"`
|
||||
_ bool `name:"authorizeSecurityGroupIngress" description:"Authorize a particular ingress/egress rule for this security group"`
|
||||
}
|
||||
|
||||
func (AuthorizeSecurityGroupIngress) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (AuthorizeSecurityGroupIngress) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (AuthorizeSecurityGroupIngress) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (AuthorizeSecurityGroupIngress) AsyncResponse() interface{} {
|
||||
return new(SecurityGroup)
|
||||
}
|
||||
|
||||
|
@ -174,11 +160,13 @@ func (req AuthorizeSecurityGroupIngress) onBeforeSend(params url.Values) error {
|
|||
// AuthorizeSecurityGroupEgress (Async) represents the egress rule creation
|
||||
type AuthorizeSecurityGroupEgress AuthorizeSecurityGroupIngress
|
||||
|
||||
func (AuthorizeSecurityGroupEgress) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (AuthorizeSecurityGroupEgress) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (AuthorizeSecurityGroupEgress) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (AuthorizeSecurityGroupEgress) AsyncResponse() interface{} {
|
||||
return new(SecurityGroup)
|
||||
}
|
||||
|
||||
|
@ -192,11 +180,14 @@ type RevokeSecurityGroupIngress struct {
|
|||
_ bool `name:"revokeSecurityGroupIngress" description:"Deletes a particular ingress rule from this security group"`
|
||||
}
|
||||
|
||||
func (RevokeSecurityGroupIngress) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RevokeSecurityGroupIngress) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
func (RevokeSecurityGroupIngress) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (RevokeSecurityGroupIngress) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// RevokeSecurityGroupEgress (Async) represents the ingress/egress rule deletion
|
||||
|
@ -205,22 +196,22 @@ type RevokeSecurityGroupEgress struct {
|
|||
_ bool `name:"revokeSecurityGroupEgress" description:"Deletes a particular egress rule from this security group"`
|
||||
}
|
||||
|
||||
func (RevokeSecurityGroupEgress) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RevokeSecurityGroupEgress) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (RevokeSecurityGroupEgress) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (RevokeSecurityGroupEgress) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListSecurityGroups
|
||||
|
||||
// ListSecurityGroups represents a search for security groups
|
||||
type ListSecurityGroups struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ID *UUID `json:"id,omitempty" doc:"list the security group by the id provided"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
SecurityGroupName string `json:"securitygroupname,omitempty" doc:"lists security groups by name"`
|
||||
|
@ -233,31 +224,3 @@ type ListSecurityGroupsResponse struct {
|
|||
Count int `json:"count"`
|
||||
SecurityGroup []SecurityGroup `json:"securitygroup"`
|
||||
}
|
||||
|
||||
func (ListSecurityGroups) response() interface{} {
|
||||
return new(ListSecurityGroupsResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (lsg *ListSecurityGroups) SetPage(page int) {
|
||||
lsg.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (lsg *ListSecurityGroups) SetPageSize(pageSize int) {
|
||||
lsg.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListSecurityGroups) each(resp interface{}, callback IterateItemFunc) {
|
||||
sgs, ok := resp.(*ListSecurityGroupsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type. ListSecurityGroupsResponse expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range sgs.SecurityGroup {
|
||||
if !callback(&sgs.SecurityGroup[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/securitygroups_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/securitygroups_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListSecurityGroups) Response() interface{} {
|
||||
return new(ListSecurityGroupsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListSecurityGroups) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListSecurityGroups) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListSecurityGroups) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListSecurityGroups) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListSecurityGroupsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListSecurityGroupsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.SecurityGroup {
|
||||
if !callback(&items.SecurityGroup[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
362
vendor/github.com/exoscale/egoscale/serialization.go
generated
vendored
362
vendor/github.com/exoscale/egoscale/serialization.go
generated
vendored
|
@ -54,7 +54,9 @@ func info(command interface{}) (*CommandInfo, error) {
|
|||
// prepareValues uses a command to build a POST request
|
||||
//
|
||||
// command is not a Command so it's easier to Test
|
||||
func prepareValues(prefix string, params url.Values, command interface{}) error {
|
||||
func prepareValues(prefix string, command interface{}) (url.Values, error) {
|
||||
params := url.Values{}
|
||||
|
||||
value := reflect.ValueOf(command)
|
||||
typeof := reflect.TypeOf(command)
|
||||
|
||||
|
@ -66,7 +68,7 @@ func prepareValues(prefix string, params url.Values, command interface{}) error
|
|||
|
||||
// Checking for nil commands
|
||||
if !value.IsValid() {
|
||||
return fmt.Errorf("cannot serialize the invalid value %#v", command)
|
||||
return nil, fmt.Errorf("cannot serialize the invalid value %#v", command)
|
||||
}
|
||||
|
||||
for i := 0; i < typeof.NumField(); i++ {
|
||||
|
@ -77,119 +79,246 @@ func prepareValues(prefix string, params url.Values, command interface{}) error
|
|||
|
||||
val := value.Field(i)
|
||||
tag := field.Tag
|
||||
|
||||
var err error
|
||||
var name string
|
||||
var value interface{}
|
||||
|
||||
if json, ok := tag.Lookup("json"); ok {
|
||||
n, required := ExtractJSONTag(field.Name, json)
|
||||
name := prefix + n
|
||||
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(), n, val.Kind())
|
||||
}
|
||||
} else {
|
||||
params.Set(name, strconv.FormatInt(v, 10))
|
||||
}
|
||||
value, err = prepareInt(val.Int(), required)
|
||||
|
||||
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(), n, val.Kind())
|
||||
}
|
||||
} else {
|
||||
params.Set(name, strconv.FormatUint(v, 10))
|
||||
}
|
||||
value, err = prepareUint(val.Uint(), required)
|
||||
|
||||
case reflect.Float32, reflect.Float64:
|
||||
v := val.Float()
|
||||
if v == 0 {
|
||||
value, err = prepareFloat(val.Float(), required)
|
||||
|
||||
case reflect.String:
|
||||
value, err = prepareString(val.String(), required)
|
||||
|
||||
case reflect.Bool:
|
||||
value, err = prepareBool(val.Bool(), required)
|
||||
|
||||
case reflect.Map:
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got 0", typeof.Name(), n, val.Kind())
|
||||
err = fmt.Errorf("field is required, got empty map")
|
||||
}
|
||||
} else {
|
||||
params.Set(name, strconv.FormatFloat(v, 'f', -1, 64))
|
||||
value, err = prepareMap(name, val.Interface())
|
||||
}
|
||||
case reflect.String:
|
||||
v := val.String()
|
||||
|
||||
case reflect.Ptr:
|
||||
value, err = preparePtr(field.Type.Elem().Kind(), val, required)
|
||||
|
||||
case reflect.Slice:
|
||||
value, err = prepareSlice(name, field.Type, val, required)
|
||||
|
||||
case reflect.Struct:
|
||||
value, err = prepareStruct(val.Interface(), required)
|
||||
|
||||
default:
|
||||
if required {
|
||||
err = fmt.Errorf("unsupported type")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch val.Kind() {
|
||||
case reflect.Struct:
|
||||
value, err = prepareEmbedStruct(val.Interface())
|
||||
default:
|
||||
log.Printf("[SKIP] %s.%s no json label found", typeof.Name(), field.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s.%s (%v) %s", typeof.Name(), field.Name, val.Kind(), err)
|
||||
}
|
||||
|
||||
switch v := value.(type) {
|
||||
case *string:
|
||||
if name != "" && v != nil {
|
||||
params.Set(name, *v)
|
||||
}
|
||||
case url.Values:
|
||||
for k, xs := range v {
|
||||
for _, x := range xs {
|
||||
params.Add(k, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func prepareInt(v int64, required bool) (*string, error) {
|
||||
if v == 0 {
|
||||
if required {
|
||||
return nil, fmt.Errorf("field is required, got %d", v)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
value := strconv.FormatInt(v, 10)
|
||||
return &value, nil
|
||||
}
|
||||
|
||||
func prepareUint(v uint64, required bool) (*string, error) {
|
||||
if v == 0 {
|
||||
if required {
|
||||
return nil, fmt.Errorf("field is required, got %d", v)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
value := strconv.FormatUint(v, 10)
|
||||
return &value, nil
|
||||
}
|
||||
|
||||
func prepareFloat(v float64, required bool) (*string, error) {
|
||||
if v == 0 {
|
||||
if required {
|
||||
return nil, fmt.Errorf("field is required, got %f", v)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
value := strconv.FormatFloat(v, 'f', -1, 64)
|
||||
return &value, nil
|
||||
}
|
||||
|
||||
func prepareString(v string, required bool) (*string, error) {
|
||||
if v == "" {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got \"\"", typeof.Name(), n, val.Kind())
|
||||
return nil, fmt.Errorf("field is required, got %q", v)
|
||||
}
|
||||
} else {
|
||||
params.Set(name, v)
|
||||
return nil, nil
|
||||
}
|
||||
case reflect.Bool:
|
||||
v := val.Bool()
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
func prepareBool(v bool, required bool) (*string, error) {
|
||||
value := strconv.FormatBool(v)
|
||||
if !v {
|
||||
if required {
|
||||
params.Set(name, "false")
|
||||
return &value, nil
|
||||
}
|
||||
} else {
|
||||
params.Set(name, "true")
|
||||
return nil, nil
|
||||
}
|
||||
case reflect.Ptr:
|
||||
|
||||
return &value, nil
|
||||
}
|
||||
|
||||
func prepareList(prefix string, slice interface{}) (url.Values, error) {
|
||||
params := url.Values{}
|
||||
value := reflect.ValueOf(slice)
|
||||
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
ps, err := prepareValues(fmt.Sprintf("%s[%d].", prefix, i), value.Index(i).Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, xs := range ps {
|
||||
for _, x := range xs {
|
||||
params.Add(k, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func prepareMap(prefix string, m interface{}) (url.Values, error) {
|
||||
value := url.Values{}
|
||||
v := reflect.ValueOf(m)
|
||||
|
||||
for i, key := range v.MapKeys() {
|
||||
var keyName string
|
||||
var keyValue string
|
||||
|
||||
switch key.Kind() {
|
||||
case reflect.String:
|
||||
keyName = key.String()
|
||||
default:
|
||||
return value, fmt.Errorf("only map[string]string are supported (XXX)")
|
||||
}
|
||||
|
||||
val := v.MapIndex(key)
|
||||
switch val.Kind() {
|
||||
case reflect.String:
|
||||
keyValue = val.String()
|
||||
default:
|
||||
return value, fmt.Errorf("only map[string]string are supported (XXX)")
|
||||
}
|
||||
|
||||
value.Set(fmt.Sprintf("%s[%d].%s", prefix, i, keyName), keyValue)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func preparePtr(kind reflect.Kind, val reflect.Value, required bool) (*string, error) {
|
||||
if val.IsNil() {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty ptr", typeof.Name(), n, val.Kind())
|
||||
return nil, fmt.Errorf("field is required, got empty ptr")
|
||||
}
|
||||
} else {
|
||||
switch field.Type.Elem().Kind() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case reflect.Bool:
|
||||
params.Set(name, strconv.FormatBool(val.Elem().Bool()))
|
||||
return prepareBool(val.Elem().Bool(), true)
|
||||
case reflect.Struct:
|
||||
i := val.Interface()
|
||||
s, ok := i.(fmt.Stringer)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s.%s (%v) is not a Stringer", typeof.Name(), field.Name, val.Kind())
|
||||
}
|
||||
if s != nil && s.String() == "" {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty value", typeof.Name(), field.Name, val.Kind())
|
||||
}
|
||||
} else {
|
||||
params.Set(n, s.String())
|
||||
}
|
||||
return prepareStruct(val.Interface(), required)
|
||||
default:
|
||||
log.Printf("[SKIP] %s.%s (%v) not supported", typeof.Name(), n, field.Type.Elem().Kind())
|
||||
return nil, fmt.Errorf("kind %v is not supported as a ptr", kind)
|
||||
}
|
||||
}
|
||||
case reflect.Slice:
|
||||
switch field.Type.Elem().Kind() {
|
||||
}
|
||||
|
||||
func prepareSlice(name string, fieldType reflect.Type, val reflect.Value, required bool) (interface{}, error) {
|
||||
switch fieldType.Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
switch field.Type {
|
||||
switch fieldType {
|
||||
case reflect.TypeOf(net.IPv4zero):
|
||||
ip := (net.IP)(val.Bytes())
|
||||
if ip == nil || ip.Equal(net.IPv4zero) {
|
||||
if ip == nil || ip.Equal(net.IP{}) {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got zero IPv4 address", typeof.Name(), n, val.Kind())
|
||||
return nil, fmt.Errorf("field is required, got zero IPv4 address")
|
||||
}
|
||||
} else {
|
||||
params.Set(name, ip.String())
|
||||
value := ip.String()
|
||||
return &value, nil
|
||||
}
|
||||
|
||||
case reflect.TypeOf(MAC48(0, 0, 0, 0, 0, 0)):
|
||||
mac := val.Interface().(MACAddress)
|
||||
s := mac.String()
|
||||
if s == "" {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty MAC address", typeof.Name(), field.Name, val.Kind())
|
||||
return nil, fmt.Errorf("field is required, got empty MAC address")
|
||||
}
|
||||
} else {
|
||||
params.Set(name, s)
|
||||
return &s, nil
|
||||
}
|
||||
default:
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), n, val.Kind())
|
||||
return nil, fmt.Errorf("field is required, got empty slice")
|
||||
}
|
||||
} else {
|
||||
v := val.Bytes()
|
||||
params.Set(name, base64.StdEncoding.EncodeToString(v))
|
||||
value := base64.StdEncoding.EncodeToString(val.Bytes())
|
||||
return &value, nil
|
||||
}
|
||||
}
|
||||
case reflect.String:
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), n, val.Kind())
|
||||
return nil, fmt.Errorf("field is required, got empty slice")
|
||||
}
|
||||
} else {
|
||||
elems := make([]string, 0, val.Len())
|
||||
|
@ -198,116 +327,61 @@ func prepareValues(prefix string, params url.Values, command interface{}) error
|
|||
s := val.Index(i).String()
|
||||
elems = append(elems, s)
|
||||
}
|
||||
params.Set(name, strings.Join(elems, ","))
|
||||
value := strings.Join(elems, ",")
|
||||
return &value, nil
|
||||
}
|
||||
default:
|
||||
switch field.Type.Elem() {
|
||||
switch fieldType.Elem() {
|
||||
case reflect.TypeOf(CIDR{}), reflect.TypeOf(UUID{}):
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), n, val.Kind())
|
||||
return nil, fmt.Errorf("field is required, got empty slice")
|
||||
}
|
||||
} else {
|
||||
value := reflect.ValueOf(val.Interface())
|
||||
v := reflect.ValueOf(val.Interface())
|
||||
ss := make([]string, val.Len())
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
v := value.Index(i).Interface()
|
||||
s, ok := v.(fmt.Stringer)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
e := v.Index(i).Interface()
|
||||
s, ok := e.(fmt.Stringer)
|
||||
if !ok {
|
||||
return fmt.Errorf("not a String, %T", v)
|
||||
return nil, fmt.Errorf("not a String, %T", e)
|
||||
}
|
||||
ss[i] = s.String()
|
||||
}
|
||||
params.Set(name, strings.Join(ss, ","))
|
||||
value := strings.Join(ss, ",")
|
||||
return &value, nil
|
||||
}
|
||||
default:
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), n, val.Kind())
|
||||
return nil, fmt.Errorf("field is required, got empty slice")
|
||||
}
|
||||
} else {
|
||||
err := prepareList(name, params, val.Interface())
|
||||
if err != nil {
|
||||
return err
|
||||
return prepareList(name, val.Interface())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
i := val.Interface()
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func prepareStruct(i interface{}, required bool) (*string, error) {
|
||||
s, ok := i.(fmt.Stringer)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s.%s (%v) is not a Stringer", typeof.Name(), field.Name, val.Kind())
|
||||
return nil, fmt.Errorf("struct field not a Stringer")
|
||||
}
|
||||
if s != nil && s.String() == "" {
|
||||
|
||||
if s == nil {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty value", typeof.Name(), field.Name, val.Kind())
|
||||
}
|
||||
} else {
|
||||
params.Set(n, s.String())
|
||||
}
|
||||
default:
|
||||
if required {
|
||||
return fmt.Errorf("unsupported type %s.%s (%v)", typeof.Name(), n, val.Kind())
|
||||
}
|
||||
fmt.Printf("%s\n", val.Kind())
|
||||
}
|
||||
} else {
|
||||
log.Printf("[SKIP] %s.%s no json label found", typeof.Name(), field.Name)
|
||||
return nil, fmt.Errorf("field is required, got %#v", s)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return prepareString(s.String(), required)
|
||||
}
|
||||
|
||||
func prepareList(prefix string, params url.Values, slice interface{}) error {
|
||||
value := reflect.ValueOf(slice)
|
||||
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
err := prepareValues(fmt.Sprintf("%s[%d].", prefix, i), params, value.Index(i).Interface())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
func prepareEmbedStruct(i interface{}) (url.Values, error) {
|
||||
return prepareValues("", i)
|
||||
}
|
||||
|
||||
// ExtractJSONTag returns the variable name or defaultName as well as if the field is required (!omitempty)
|
||||
|
|
40
vendor/github.com/exoscale/egoscale/service_offerings.go
generated
vendored
40
vendor/github.com/exoscale/egoscale/service_offerings.go
generated
vendored
|
@ -1,9 +1,5 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ServiceOffering corresponds to the Compute Offerings
|
||||
//
|
||||
// A service offering correspond to some hardware features (CPU, RAM).
|
||||
|
@ -21,11 +17,9 @@ type ServiceOffering struct {
|
|||
DiskIopsReadRate int64 `json:"diskIopsReadRate,omitempty" doc:"io requests read rate of the service offering"`
|
||||
DiskIopsWriteRate int64 `json:"diskIopsWriteRate,omitempty" doc:"io requests write rate of the service offering"`
|
||||
Displaytext string `json:"displaytext,omitempty" doc:"an alternate display text of the service offering."`
|
||||
Domain string `json:"domain,omitempty" doc:"Domain name for the offering"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain id of the service offering"`
|
||||
HostTags string `json:"hosttags,omitempty" doc:"the host tag for the service offering"`
|
||||
HypervisorSnapshotReserve int `json:"hypervisorsnapshotreserve,omitempty" doc:"Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the id of the service offering"`
|
||||
ID *UUID `json:"id" doc:"the id of the service offering"`
|
||||
IsCustomized bool `json:"iscustomized,omitempty" doc:"is true if the offering is customized"`
|
||||
IsCustomizedIops bool `json:"iscustomizediops,omitempty" doc:"true if disk offering uses custom iops, false otherwise"`
|
||||
IsSystem bool `json:"issystem,omitempty" doc:"is this a system vm offering"`
|
||||
|
@ -49,7 +43,6 @@ func (so ServiceOffering) ListRequest() (ListCommand, error) {
|
|||
// Restricted cannot be applied here because it really has three states
|
||||
req := &ListServiceOfferings{
|
||||
ID: so.ID,
|
||||
DomainID: so.DomainID,
|
||||
Name: so.Name,
|
||||
SystemVMType: so.SystemVMType,
|
||||
}
|
||||
|
@ -61,9 +54,10 @@ func (so ServiceOffering) ListRequest() (ListCommand, error) {
|
|||
return req, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListServiceOfferings
|
||||
|
||||
// ListServiceOfferings represents a query for service offerings
|
||||
type ListServiceOfferings struct {
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the ID of the domain associated with the service offering"`
|
||||
ID *UUID `json:"id,omitempty" doc:"ID of the service offering"`
|
||||
IsSystem *bool `json:"issystem,omitempty" doc:"is this a system vm offering"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
|
@ -81,31 +75,3 @@ type ListServiceOfferingsResponse struct {
|
|||
Count int `json:"count"`
|
||||
ServiceOffering []ServiceOffering `json:"serviceoffering"`
|
||||
}
|
||||
|
||||
func (ListServiceOfferings) response() interface{} {
|
||||
return new(ListServiceOfferingsResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (lso *ListServiceOfferings) SetPage(page int) {
|
||||
lso.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (lso *ListServiceOfferings) SetPageSize(pageSize int) {
|
||||
lso.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListServiceOfferings) each(resp interface{}, callback IterateItemFunc) {
|
||||
sos, ok := resp.(*ListServiceOfferingsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type. ListServiceOfferingsResponse expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range sos.ServiceOffering {
|
||||
if !callback(&sos.ServiceOffering[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/serviceofferings_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/serviceofferings_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListServiceOfferings) Response() interface{} {
|
||||
return new(ListServiceOfferingsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListServiceOfferings) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListServiceOfferings) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListServiceOfferings) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListServiceOfferings) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListServiceOfferingsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListServiceOfferingsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.ServiceOffering {
|
||||
if !callback(&items.ServiceOffering[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
74
vendor/github.com/exoscale/egoscale/snapshots.go
generated
vendored
74
vendor/github.com/exoscale/egoscale/snapshots.go
generated
vendored
|
@ -3,28 +3,27 @@ package egoscale
|
|||
// SnapshotState represents the Snapshot.State enum
|
||||
//
|
||||
// See: https://github.com/apache/cloudstack/blob/master/api/src/main/java/com/cloud/storage/Snapshot.java
|
||||
type SnapshotState int
|
||||
type SnapshotState string
|
||||
|
||||
//go:generate stringer -type SnapshotState
|
||||
const (
|
||||
// Allocated ... (TODO)
|
||||
Allocated SnapshotState = iota
|
||||
Allocated SnapshotState = "Allocated"
|
||||
// Creating ... (TODO)
|
||||
Creating
|
||||
Creating SnapshotState = "Creating"
|
||||
// CreatedOnPrimary ... (TODO)
|
||||
CreatedOnPrimary
|
||||
CreatedOnPrimary SnapshotState = "CreatedOnPrimary"
|
||||
// BackingUp ... (TODO)
|
||||
BackingUp
|
||||
BackingUp SnapshotState = "BackingUp"
|
||||
// BackedUp ... (TODO)
|
||||
BackedUp
|
||||
BackedUp SnapshotState = "BackedUp"
|
||||
// Copying ... (TODO)
|
||||
Copying
|
||||
Copying SnapshotState = "Copying"
|
||||
// Destroying ... (TODO)
|
||||
Destroying
|
||||
Destroying SnapshotState = "Destroying"
|
||||
// Destroyed ... (TODO)
|
||||
Destroyed
|
||||
Destroyed SnapshotState = "Destroyed"
|
||||
// Error is a state where the user can't see the snapshot while the snapshot may still exist on the storage
|
||||
Error
|
||||
Error SnapshotState = "Error"
|
||||
)
|
||||
|
||||
// Snapshot represents a volume snapshot
|
||||
|
@ -32,8 +31,6 @@ type Snapshot struct {
|
|||
Account string `json:"account,omitempty" doc:"the account associated with the snapshot"`
|
||||
AccountID *UUID `json:"accountid,omitempty" doc:"the account ID associated with the snapshot"`
|
||||
Created string `json:"created,omitempty" doc:"the date the snapshot was created"`
|
||||
Domain string `json:"domain,omitempty" doc:"the domain name of the snapshot's account"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain ID of the snapshot's account"`
|
||||
ID *UUID `json:"id,omitempty" doc:"ID of the snapshot"`
|
||||
IntervalType string `json:"intervaltype,omitempty" doc:"valid types are hourly, daily, weekly, monthy, template, and none."`
|
||||
Name string `json:"name,omitempty" doc:"name of the snapshot"`
|
||||
|
@ -41,7 +38,7 @@ type Snapshot struct {
|
|||
Revertable *bool `json:"revertable,omitempty" doc:"indicates whether the underlying storage supports reverting the volume to this snapshot"`
|
||||
Size int64 `json:"size,omitempty" doc:"the size of original volume"`
|
||||
SnapshotType string `json:"snapshottype,omitempty" doc:"the type of the snapshot"`
|
||||
State SnapshotState `json:"state,omitempty" doc:"the state of the snapshot. BackedUp means that snapshot is ready to be used; Creating - the snapshot is being allocated on the primary storage; BackingUp - the snapshot is being backed up on secondary storage"`
|
||||
State string `json:"state,omitempty" doc:"the state of the snapshot. BackedUp means that snapshot is ready to be used; Creating - the snapshot is being allocated on the primary storage; BackingUp - the snapshot is being backed up on secondary storage"`
|
||||
Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with snapshot"`
|
||||
VolumeID *UUID `json:"volumeid,omitempty" doc:"ID of the disk volume"`
|
||||
VolumeName string `json:"volumename,omitempty" doc:"name of the disk volume"`
|
||||
|
@ -57,29 +54,42 @@ func (Snapshot) ResourceType() string {
|
|||
// CreateSnapshot (Async) creates an instant snapshot of a volume
|
||||
type CreateSnapshot struct {
|
||||
VolumeID *UUID `json:"volumeid" doc:"The ID of the disk volume"`
|
||||
Account string `json:"account,omitempty" doc:"The account of the snapshot. The account parameter must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"The domain ID of the snapshot. If used with the account parameter, specifies a domain for the account associated with the disk volume."`
|
||||
QuiesceVM *bool `json:"quiescevm,omitempty" doc:"quiesce vm if true"`
|
||||
_ bool `name:"createSnapshot" description:"Creates an instant snapshot of a volume."`
|
||||
}
|
||||
|
||||
func (CreateSnapshot) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (CreateSnapshot) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (CreateSnapshot) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (CreateSnapshot) AsyncResponse() interface{} {
|
||||
return new(Snapshot)
|
||||
}
|
||||
|
||||
// ListRequest builds the ListSnapshot request
|
||||
func (ss Snapshot) ListRequest() (ListCommand, error) {
|
||||
// Restricted cannot be applied here because it really has three states
|
||||
req := &ListSnapshots{
|
||||
ID: ss.ID,
|
||||
Name: ss.Name,
|
||||
VolumeID: ss.VolumeID,
|
||||
SnapshotType: ss.SnapshotType,
|
||||
ZoneID: ss.ZoneID,
|
||||
// TODO: tags
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListSnapshots
|
||||
|
||||
// ListSnapshots lists the volume snapshots
|
||||
type ListSnapshots struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ID *UUID `json:"id,omitempty" doc:"lists snapshot by snapshot ID"`
|
||||
IntervalType string `json:"intervaltype,omitempty" doc:"valid values are HOURLY, DAILY, WEEKLY, and MONTHLY."`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Name string `json:"name,omitempty" doc:"lists snapshot by snapshot name"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
|
@ -96,22 +106,20 @@ type ListSnapshotsResponse struct {
|
|||
Snapshot []Snapshot `json:"snapshot"`
|
||||
}
|
||||
|
||||
func (ListSnapshots) response() interface{} {
|
||||
return new(ListSnapshotsResponse)
|
||||
}
|
||||
|
||||
// DeleteSnapshot (Async) deletes a snapshot of a disk volume
|
||||
type DeleteSnapshot struct {
|
||||
ID *UUID `json:"id" doc:"The ID of the snapshot"`
|
||||
_ bool `name:"deleteSnapshot" description:"Deletes a snapshot of a disk volume."`
|
||||
}
|
||||
|
||||
func (DeleteSnapshot) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (DeleteSnapshot) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (DeleteSnapshot) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (DeleteSnapshot) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// RevertSnapshot (Async) reverts a volume snapshot
|
||||
|
@ -120,10 +128,12 @@ type RevertSnapshot struct {
|
|||
_ bool `name:"revertSnapshot" description:"revert a volume snapshot."`
|
||||
}
|
||||
|
||||
func (RevertSnapshot) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RevertSnapshot) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (RevertSnapshot) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (RevertSnapshot) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/snapshots_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/snapshots_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListSnapshots) Response() interface{} {
|
||||
return new(ListSnapshotsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListSnapshots) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListSnapshots) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListSnapshots) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListSnapshots) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListSnapshotsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListSnapshotsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.Snapshot {
|
||||
if !callback(&items.Snapshot[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
16
vendor/github.com/exoscale/egoscale/snapshotstate_string.go
generated
vendored
16
vendor/github.com/exoscale/egoscale/snapshotstate_string.go
generated
vendored
|
@ -1,16 +0,0 @@
|
|||
// Code generated by "stringer -type SnapshotState"; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "strconv"
|
||||
|
||||
const _SnapshotState_name = "AllocatedCreatingCreatedOnPrimaryBackingUpBackedUpCopyingDestroyingDestroyedError"
|
||||
|
||||
var _SnapshotState_index = [...]uint8{0, 9, 17, 33, 42, 50, 57, 67, 76, 81}
|
||||
|
||||
func (i SnapshotState) String() string {
|
||||
if i < 0 || i >= SnapshotState(len(_SnapshotState_index)-1) {
|
||||
return "SnapshotState(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _SnapshotState_name[_SnapshotState_index[i]:_SnapshotState_index[i+1]]
|
||||
}
|
61
vendor/github.com/exoscale/egoscale/ssh_keypairs.go
generated
vendored
61
vendor/github.com/exoscale/egoscale/ssh_keypairs.go
generated
vendored
|
@ -38,48 +38,43 @@ func (ssh SSHKeyPair) ListRequest() (ListCommand, error) {
|
|||
// CreateSSHKeyPair represents a new keypair to be created
|
||||
type CreateSSHKeyPair struct {
|
||||
Name string `json:"name" doc:"Name of the keypair"`
|
||||
Account string `json:"account,omitempty" doc:"an optional account for the ssh key. Must be used with domainId."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"an optional domainId for the ssh key. If the account parameter is used, domainId must also be used."`
|
||||
_ bool `name:"createSSHKeyPair" description:"Create a new keypair and returns the private key"`
|
||||
}
|
||||
|
||||
func (CreateSSHKeyPair) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (CreateSSHKeyPair) Response() interface{} {
|
||||
return new(SSHKeyPair)
|
||||
}
|
||||
|
||||
// DeleteSSHKeyPair represents a new keypair to be created
|
||||
type DeleteSSHKeyPair struct {
|
||||
Name string `json:"name" doc:"Name of the keypair"`
|
||||
Account string `json:"account,omitempty" doc:"the account associated with the keypair. Must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain ID associated with the keypair"`
|
||||
_ bool `name:"deleteSSHKeyPair" description:"Deletes a keypair by name"`
|
||||
}
|
||||
|
||||
func (DeleteSSHKeyPair) response() interface{} {
|
||||
return new(booleanResponse)
|
||||
// Response returns the struct to unmarshal
|
||||
func (DeleteSSHKeyPair) Response() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// RegisterSSHKeyPair represents a new registration of a public key in a keypair
|
||||
type RegisterSSHKeyPair struct {
|
||||
Name string `json:"name" doc:"Name of the keypair"`
|
||||
PublicKey string `json:"publickey" doc:"Public key material of the keypair"`
|
||||
Account string `json:"account,omitempty" doc:"an optional account for the ssh key. Must be used with domainId."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"an optional domainId for the ssh key. If the account parameter is used, domainId must also be used."`
|
||||
_ bool `name:"registerSSHKeyPair" description:"Register a public key in a keypair under a certain name"`
|
||||
}
|
||||
|
||||
func (RegisterSSHKeyPair) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RegisterSSHKeyPair) Response() interface{} {
|
||||
return new(SSHKeyPair)
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListSSHKeyPairs
|
||||
|
||||
// ListSSHKeyPairs represents a query for a list of SSH KeyPairs
|
||||
type ListSSHKeyPairs struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
Fingerprint string `json:"fingerprint,omitempty" doc:"A public key fingerprint to look for"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Name string `json:"name,omitempty" doc:"A key pair name to look for"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
|
@ -92,47 +87,19 @@ type ListSSHKeyPairsResponse struct {
|
|||
SSHKeyPair []SSHKeyPair `json:"sshkeypair"`
|
||||
}
|
||||
|
||||
func (ListSSHKeyPairs) response() interface{} {
|
||||
return new(ListSSHKeyPairsResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (ls *ListSSHKeyPairs) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListSSHKeyPairs) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListSSHKeyPairs) each(resp interface{}, callback IterateItemFunc) {
|
||||
sshs, ok := resp.(*ListSSHKeyPairsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type. ListSSHKeyPairsResponse expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range sshs.SSHKeyPair {
|
||||
if !callback(&sshs.SSHKeyPair[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ResetSSHKeyForVirtualMachine (Async) represents a change for the key pairs
|
||||
type ResetSSHKeyForVirtualMachine struct {
|
||||
ID *UUID `json:"id" doc:"The ID of the virtual machine"`
|
||||
KeyPair string `json:"keypair" doc:"name of the ssh key pair used to login to the virtual machine"`
|
||||
Account string `json:"account,omitempty" doc:"an optional account for the ssh key. Must be used with domainId."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used."`
|
||||
KeyPair string `json:"keypair" doc:"Name of the ssh key pair used to login to the virtual machine"`
|
||||
_ bool `name:"resetSSHKeyForVirtualMachine" description:"Resets the SSH Key for virtual machine. The virtual machine must be in a \"Stopped\" state."`
|
||||
}
|
||||
|
||||
func (ResetSSHKeyForVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (ResetSSHKeyForVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (ResetSSHKeyForVirtualMachine) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (ResetSSHKeyForVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/sshkeypairs_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/sshkeypairs_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListSSHKeyPairs) Response() interface{} {
|
||||
return new(ListSSHKeyPairsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListSSHKeyPairs) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListSSHKeyPairs) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListSSHKeyPairs) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListSSHKeyPairs) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListSSHKeyPairsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListSSHKeyPairsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.SSHKeyPair {
|
||||
if !callback(&items.SSHKeyPair[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
43
vendor/github.com/exoscale/egoscale/tags.go
generated
vendored
43
vendor/github.com/exoscale/egoscale/tags.go
generated
vendored
|
@ -2,18 +2,29 @@ package egoscale
|
|||
|
||||
// ResourceTag is a tag associated with a resource
|
||||
//
|
||||
// http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/4.9/management.html
|
||||
// https://community.exoscale.com/documentation/compute/instance-tags/
|
||||
type ResourceTag struct {
|
||||
Account string `json:"account,omitempty" doc:"the account associated with the tag"`
|
||||
Customer string `json:"customer,omitempty" doc:"customer associated with the tag"`
|
||||
Domain string `json:"domain,omitempty" doc:"the domain associated with the tag"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the ID of the domain associated with the tag"`
|
||||
Key string `json:"key,omitempty" doc:"tag key name"`
|
||||
ResourceID *UUID `json:"resourceid,omitempty" doc:"id of the resource"`
|
||||
ResourceType string `json:"resourcetype,omitempty" doc:"resource type"`
|
||||
Value string `json:"value,omitempty" doc:"tag value"`
|
||||
}
|
||||
|
||||
// ListRequest builds the ListZones request
|
||||
func (tag ResourceTag) ListRequest() (ListCommand, error) {
|
||||
req := &ListTags{
|
||||
Customer: tag.Customer,
|
||||
Key: tag.Key,
|
||||
ResourceID: tag.ResourceID,
|
||||
ResourceType: tag.ResourceType,
|
||||
Value: tag.Value,
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// CreateTags (Async) creates resource tag(s)
|
||||
type CreateTags struct {
|
||||
ResourceIDs []UUID `json:"resourceids" doc:"list of resources to create the tags for"`
|
||||
|
@ -23,12 +34,14 @@ type CreateTags struct {
|
|||
_ bool `name:"createTags" description:"Creates resource tag(s)"`
|
||||
}
|
||||
|
||||
func (CreateTags) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (CreateTags) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (CreateTags) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (CreateTags) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// DeleteTags (Async) deletes the resource tag(s)
|
||||
|
@ -39,23 +52,23 @@ type DeleteTags struct {
|
|||
_ bool `name:"deleteTags" description:"Deleting resource tag(s)"`
|
||||
}
|
||||
|
||||
func (DeleteTags) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (DeleteTags) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (DeleteTags) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (DeleteTags) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListTags
|
||||
|
||||
// ListTags list resource tag(s)
|
||||
type ListTags struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
Customer string `json:"customer,omitempty" doc:"list by customer name"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Key string `json:"key,omitempty" doc:"list by key"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
ResourceID *UUID `json:"resourceid,omitempty" doc:"list by resource id"`
|
||||
|
@ -69,7 +82,3 @@ type ListTagsResponse struct {
|
|||
Count int `json:"count"`
|
||||
Tag []ResourceTag `json:"tag"`
|
||||
}
|
||||
|
||||
func (ListTags) response() interface{} {
|
||||
return new(ListTagsResponse)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/tags_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/tags_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListTags) Response() interface{} {
|
||||
return new(ListTagsResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListTags) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListTags) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListTags) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListTags) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListTagsResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListTagsResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.Tag {
|
||||
if !callback(&items.Tag[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
221
vendor/github.com/exoscale/egoscale/templates.go
generated
vendored
221
vendor/github.com/exoscale/egoscale/templates.go
generated
vendored
|
@ -1,12 +1,6 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Template represents a machine to be deployed
|
||||
//
|
||||
// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/templates.html
|
||||
// Template represents a machine to be deployed.
|
||||
type Template struct {
|
||||
Account string `json:"account,omitempty" doc:"the account name to which the template belongs"`
|
||||
AccountID *UUID `json:"accountid,omitempty" doc:"the account id to which the template belongs"`
|
||||
|
@ -16,12 +10,9 @@ type Template struct {
|
|||
CrossZones bool `json:"crossZones,omitempty" doc:"true if the template is managed across all Zones, false otherwise"`
|
||||
Details map[string]string `json:"details,omitempty" doc:"additional key/value details tied with template"`
|
||||
DisplayText string `json:"displaytext,omitempty" doc:"the template display text"`
|
||||
Domain string `json:"domain,omitempty" doc:"the name of the domain to which the template belongs"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the ID of the domain to which the template belongs"`
|
||||
Format string `json:"format,omitempty" doc:"the format of the template."`
|
||||
HostID *UUID `json:"hostid,omitempty" doc:"the ID of the secondary storage host for the template"`
|
||||
HostName string `json:"hostname,omitempty" doc:"the name of the secondary storage host for the template"`
|
||||
Hypervisor string `json:"hypervisor,omitempty" doc:"the hypervisor on which the template runs"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the template ID"`
|
||||
IsDynamicallyScalable bool `json:"isdynamicallyscalable,omitempty" doc:"true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory"`
|
||||
IsExtractable bool `json:"isextractable,omitempty" doc:"true if the template is extractable, false otherwise"`
|
||||
|
@ -52,42 +43,39 @@ func (Template) ResourceType() string {
|
|||
}
|
||||
|
||||
// ListRequest builds the ListTemplates request
|
||||
func (temp Template) ListRequest() (ListCommand, error) {
|
||||
func (template Template) ListRequest() (ListCommand, error) {
|
||||
req := &ListTemplates{
|
||||
Name: temp.Name,
|
||||
Account: temp.Account,
|
||||
DomainID: temp.DomainID,
|
||||
ID: temp.ID,
|
||||
ZoneID: temp.ZoneID,
|
||||
Hypervisor: temp.Hypervisor,
|
||||
//TODO Tags
|
||||
ID: template.ID,
|
||||
Name: template.Name,
|
||||
ZoneID: template.ZoneID,
|
||||
}
|
||||
if temp.IsFeatured {
|
||||
if template.IsFeatured {
|
||||
req.TemplateFilter = "featured"
|
||||
}
|
||||
if temp.Removed != "" {
|
||||
if template.Removed != "" {
|
||||
*req.ShowRemoved = true
|
||||
}
|
||||
|
||||
for i := range template.Tags {
|
||||
req.Tags = append(req.Tags, template.Tags[i])
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListTemplates
|
||||
|
||||
// ListTemplates represents a template query filter
|
||||
type ListTemplates struct {
|
||||
TemplateFilter string `json:"templatefilter" doc:"possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". * featured : templates that have been marked as featured and public. * self : templates that have been registered or created by the calling user. * selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. * sharedexecutable : templates ready to be deployed that have been granted to the calling user by another user. * executable : templates that are owned by the calling user, or public templates, that can be used to deploy a VM. * community : templates that have been marked as public but not featured. * all : all templates (only usable by admins)."`
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
Hypervisor string `json:"hypervisor,omitempty" doc:"the hypervisor for which to restrict the search"`
|
||||
TemplateFilter string `json:"templatefilter" doc:"Possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". * featured : templates that have been marked as featured and public. * self : templates that have been registered or created by the calling user. * selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. * sharedexecutable : templates ready to be deployed that have been granted to the calling user by another user. * executable : templates that are owned by the calling user, or public templates, that can be used to deploy a VM. * community : templates that have been marked as public but not featured."`
|
||||
ID *UUID `json:"id,omitempty" doc:"the template ID"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Name string `json:"name,omitempty" doc:"the template name"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
ShowRemoved *bool `json:"showremoved,omitempty" doc:"show removed templates as well"`
|
||||
ShowRemoved *bool `json:"showremoved,omitempty" doc:"Show removed templates as well"`
|
||||
Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"list templates by zoneId"`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"list templates by zoneid"`
|
||||
_ bool `name:"listTemplates" description:"List all public, private, and privileged templates."`
|
||||
}
|
||||
|
||||
|
@ -97,172 +85,27 @@ type ListTemplatesResponse struct {
|
|||
Template []Template `json:"template"`
|
||||
}
|
||||
|
||||
func (ListTemplates) response() interface{} {
|
||||
return new(ListTemplatesResponse)
|
||||
}
|
||||
|
||||
func (ListTemplates) each(resp interface{}, callback IterateItemFunc) {
|
||||
temps, ok := resp.(*ListTemplatesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type. ListTemplatesResponse expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range temps.Template {
|
||||
if !callback(&temps.Template[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (ls *ListTemplates) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListTemplates) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// CreateTemplate (Async) represents a template creation
|
||||
type CreateTemplate struct {
|
||||
Bits int `json:"bits,omitempty" doc:"32 or 64 bit"`
|
||||
Details map[string]string `json:"details,omitempty" doc:"Template details in key/value pairs."`
|
||||
DisplayText string `json:"displaytext" doc:"the display text of the template. This is usually used for display purposes."`
|
||||
IsDynamicallyScalable *bool `json:"isdynamicallyscalable,omitempty" doc:"true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory"`
|
||||
IsFeatured *bool `json:"isfeatured,omitempty" doc:"true if this template is a featured template, false otherwise"`
|
||||
IsPublic *bool `json:"ispublic,omitempty" doc:"true if this template is a public template, false otherwise"`
|
||||
Name string `json:"name" doc:"the name of the template"`
|
||||
OsTypeID *UUID `json:"ostypeid" doc:"the ID of the OS Type that best represents the OS of this template."`
|
||||
PasswordEnabled *bool `json:"passwordenabled,omitempty" doc:"true if the template supports the password reset feature; default is false"`
|
||||
RequiresHVM *bool `json:"requireshvm,omitempty" doc:"true if the template requres HVM, false otherwise"`
|
||||
SnapshotID *UUID `json:"snapshotid,omitempty" doc:"the ID of the snapshot the template is being created from. Either this parameter, or volumeId has to be passed in"`
|
||||
TemplateTag string `json:"templatetag,omitempty" doc:"the tag for this template."`
|
||||
URL string `json:"url,omitempty" doc:"Optional, only for baremetal hypervisor. The directory name where template stored on CIFS server"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"Optional, VM ID. If this presents, it is going to create a baremetal template for VM this ID refers to. This is only for VM whose hypervisor type is BareMetal"`
|
||||
VolumeID *UUID `json:"volumeid,omitempty" doc:"the ID of the disk volume the template is being created from. Either this parameter, or snapshotId has to be passed in"`
|
||||
_ bool `name:"createTemplate" description:"Creates a template of a virtual machine. The virtual machine must be in a STOPPED state. A template created from this command is automatically designated as a private template visible to the account that created it."`
|
||||
}
|
||||
|
||||
func (CreateTemplate) response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (CreateTemplate) asyncResponse() interface{} {
|
||||
return new(Template)
|
||||
}
|
||||
|
||||
// CopyTemplate (Async) represents a template copy
|
||||
type CopyTemplate struct {
|
||||
DestZoneID *UUID `json:"destzoneid" doc:"ID of the zone the template is being copied to."`
|
||||
ID *UUID `json:"id" doc:"Template ID."`
|
||||
SourceZoneID *UUID `json:"sourcezoneid,omitempty" doc:"ID of the zone the template is currently hosted on. If not specified and template is cross-zone, then we will sync this template to region wide image store."`
|
||||
_ bool `name:"copyTemplate" description:"Copies a template from one zone to another."`
|
||||
}
|
||||
|
||||
func (CopyTemplate) response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (CopyTemplate) asyncResponse() interface{} {
|
||||
return new(Template)
|
||||
}
|
||||
|
||||
// UpdateTemplate represents a template change
|
||||
type UpdateTemplate struct {
|
||||
Bootable *bool `json:"bootable,omitempty" doc:"true if image is bootable, false otherwise"`
|
||||
Details map[string]string `json:"details,omitempty" doc:"Details in key/value pairs."`
|
||||
DisplayText string `json:"displaytext,omitempty" doc:"the display text of the image"`
|
||||
Format string `json:"format,omitempty" doc:"the format for the image"`
|
||||
ID *UUID `json:"id" doc:"the ID of the image file"`
|
||||
IsDynamicallyScalable *bool `json:"isdynamicallyscalable,omitempty" doc:"true if template/ISO contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory"`
|
||||
IsRouting *bool `json:"isrouting,omitempty" doc:"true if the template type is routing i.e., if template is used to deploy router"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the image file"`
|
||||
OsTypeID *UUID `json:"ostypeid,omitempty" doc:"the ID of the OS type that best represents the OS of this image."`
|
||||
PasswordEnabled *bool `json:"passwordenabled,omitempty" doc:"true if the image supports the password reset feature; default is false"`
|
||||
SortKey int `json:"sortkey,omitempty" doc:"sort key of the template, integer"`
|
||||
_ bool `name:"updateTemplate" description:"Updates attributes of a template."`
|
||||
}
|
||||
|
||||
func (UpdateTemplate) response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (UpdateTemplate) asyncResponse() interface{} {
|
||||
return new(Template)
|
||||
}
|
||||
|
||||
// DeleteTemplate (Async) represents the deletion of a template
|
||||
type DeleteTemplate struct {
|
||||
ID *UUID `json:"id" doc:"the ID of the template"`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"the ID of zone of the template"`
|
||||
_ bool `name:"deleteTemplate" description:"Deletes a template from the system. All virtual machines using the deleted template will not be affected."`
|
||||
}
|
||||
|
||||
func (DeleteTemplate) response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (DeleteTemplate) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
}
|
||||
|
||||
// PrepareTemplate represents a template preparation
|
||||
type PrepareTemplate struct {
|
||||
TemplateID *UUID `json:"templateid" doc:"template ID of the template to be prepared in primary storage(s)."`
|
||||
ZoneID *UUID `json:"zoneid" doc:"zone ID of the template to be prepared in primary storage(s)."`
|
||||
_ bool `name:"prepareTemplate" description:"load template into primary storage"`
|
||||
}
|
||||
|
||||
func (PrepareTemplate) response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (PrepareTemplate) asyncResponse() interface{} {
|
||||
return new(Template)
|
||||
}
|
||||
|
||||
// RegisterTemplate represents a template registration
|
||||
type RegisterTemplate struct {
|
||||
Account string `json:"account,omitempty" doc:"an optional accountName. Must be used with domainId."`
|
||||
Bits int `json:"bits,omitempty" doc:"32 or 64 bits support. 64 by default"`
|
||||
Checksum string `json:"checksum,omitempty" doc:"the MD5 checksum value of this template"`
|
||||
Details map[string]string `json:"details,omitempty" doc:"Template details in key/value pairs."`
|
||||
DisplayText string `json:"displaytext" doc:"the display text of the template. This is usually used for display purposes."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"an optional domainId. If the account parameter is used, domainId must also be used."`
|
||||
Format string `json:"format" doc:"the format for the template. Possible values include QCOW2, RAW, and VHD."`
|
||||
Hypervisor string `json:"hypervisor" doc:"the target hypervisor for the template"`
|
||||
IsDynamicallyScalable *bool `json:"isdynamicallyscalable,omitempty" doc:"true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory"`
|
||||
IsExtractable *bool `json:"isextractable,omitempty" doc:"true if the template or its derivatives are extractable; default is false"`
|
||||
IsFeatured *bool `json:"isfeatured,omitempty" doc:"true if this template is a featured template, false otherwise"`
|
||||
IsPublic *bool `json:"ispublic,omitempty" doc:"true if the template is available to all accounts; default is true"`
|
||||
IsRouting *bool `json:"isrouting,omitempty" doc:"true if the template type is routing i.e., if template is used to deploy router"`
|
||||
IsSystem *bool `json:"issystem,omitempty" doc:"true if the template type is system i.e., if template is used to deploy system VM"`
|
||||
Name string `json:"name" doc:"the name of the template"`
|
||||
OsTypeID *UUID `json:"ostypeid" doc:"the ID of the OS Type that best represents the OS of this template."`
|
||||
PasswordEnabled *bool `json:"passwordenabled,omitempty" doc:"true if the template supports the password reset feature; default is false"`
|
||||
RequiresHVM *bool `json:"requireshvm,omitempty" doc:"true if this template requires HVM"`
|
||||
SSHKeyEnabled *bool `json:"sshkeyenabled,omitempty" doc:"true if the template supports the sshkey upload feature; default is false"`
|
||||
TemplateTag string `json:"templatetag,omitempty" doc:"the tag for this template."`
|
||||
URL string `json:"url" doc:"the URL of where the template is hosted. Possible URL include http:// and https://"`
|
||||
ZoneID *UUID `json:"zoneid" doc:"the ID of the zone the template is to be hosted on"`
|
||||
_ bool `name:"registerTemplate" description:"Registers an existing template into the CloudStack cloud."`
|
||||
}
|
||||
|
||||
func (RegisterTemplate) response() interface{} {
|
||||
return new(Template)
|
||||
}
|
||||
|
||||
// OSCategory represents an OS category
|
||||
type OSCategory struct {
|
||||
ID string `json:"id,omitempty" doc:"the ID of the OS category"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the ID of the OS category"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the OS category"`
|
||||
}
|
||||
|
||||
// ListRequest builds the ListOSCategories request
|
||||
func (osCat OSCategory) ListRequest() (ListCommand, error) {
|
||||
req := &ListOSCategories{
|
||||
Name: osCat.Name,
|
||||
ID: osCat.ID,
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListOSCategories
|
||||
|
||||
// ListOSCategories lists the OS categories
|
||||
type ListOSCategories struct {
|
||||
ID string `json:"id,omitempty" doc:"list Os category by id"`
|
||||
ID *UUID `json:"id,omitempty" doc:"list Os category by id"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
Name string `json:"name,omitempty" doc:"list os category by name"`
|
||||
Page int `json:"page,omitempty"`
|
||||
|
@ -275,7 +118,3 @@ type ListOSCategoriesResponse struct {
|
|||
Count int `json:"count"`
|
||||
OSCategory []OSCategory `json:"oscategory"`
|
||||
}
|
||||
|
||||
func (ListOSCategories) response() interface{} {
|
||||
return new(ListOSCategoriesResponse)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/templates_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/templates_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListTemplates) Response() interface{} {
|
||||
return new(ListTemplatesResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListTemplates) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListTemplates) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListTemplates) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListTemplates) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListTemplatesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListTemplatesResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.Template {
|
||||
if !callback(&items.Template[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
74
vendor/github.com/exoscale/egoscale/users.go
generated
vendored
74
vendor/github.com/exoscale/egoscale/users.go
generated
vendored
|
@ -5,14 +5,10 @@ type User struct {
|
|||
APIKey string `json:"apikey,omitempty" doc:"the api key of the user"`
|
||||
Account string `json:"account,omitempty" doc:"the account name of the user"`
|
||||
AccountID *UUID `json:"accountid,omitempty" doc:"the account ID of the user"`
|
||||
AccountType int16 `json:"accounttype,omitempty" doc:"the account type of the user"`
|
||||
Created string `json:"created,omitempty" doc:"the date and time the user account was created"`
|
||||
Domain string `json:"domain,omitempty" doc:"the domain name of the user"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain ID of the user"`
|
||||
Email string `json:"email,omitempty" doc:"the user email address"`
|
||||
FirstName string `json:"firstname,omitempty" doc:"the user firstname"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the user ID"`
|
||||
IsCallerChildDomain bool `json:"iscallerchilddomain,omitempty" doc:"the boolean value representing if the updating target is in caller's child domain"`
|
||||
IsDefault bool `json:"isdefault,omitempty" doc:"true if user is default, false otherwise"`
|
||||
LastName string `json:"lastname,omitempty" doc:"the user lastname"`
|
||||
RoleID *UUID `json:"roleid,omitempty" doc:"the ID of the role"`
|
||||
|
@ -24,6 +20,16 @@ type User struct {
|
|||
UserName string `json:"username,omitempty" doc:"the user name"`
|
||||
}
|
||||
|
||||
// ListRequest builds the ListUsers request
|
||||
func (user User) ListRequest() (ListCommand, error) {
|
||||
req := &ListUsers{
|
||||
ID: user.ID,
|
||||
UserName: user.UserName,
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// RegisterUserKeys registers a new set of key of the given user
|
||||
//
|
||||
// NB: only the APIKey and SecretKey will be filled
|
||||
|
@ -32,59 +38,21 @@ type RegisterUserKeys struct {
|
|||
_ bool `name:"registerUserKeys" description:"This command allows a user to register for the developer API, returning a secret key and an API key. This request is made through the integration API port, so it is a privileged command and must be made on behalf of a user. It is up to the implementer just how the username and password are entered, and then how that translates to an integration API request. Both secret key and API key should be returned to the user"`
|
||||
}
|
||||
|
||||
func (RegisterUserKeys) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RegisterUserKeys) Response() interface{} {
|
||||
return new(User)
|
||||
}
|
||||
|
||||
// CreateUser represents the creation of a User
|
||||
type CreateUser struct {
|
||||
Account string `json:"account" doc:"Creates the user under the specified account. If no account is specified, the username will be used as the account name."`
|
||||
Email string `json:"email" doc:"email"`
|
||||
FirstName string `json:"firstname" doc:"firstname"`
|
||||
LastName string `json:"lastname" doc:"lastname"`
|
||||
Password string `json:"password" doc:"Clear text password (Default hashed to SHA256SALT). If you wish to use any other hashing algorithm, you would need to write a custom authentication adapter See Docs section."`
|
||||
UserName string `json:"username" doc:"Unique username."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"Creates the user under the specified domain. Has to be accompanied with the account parameter"`
|
||||
Timezone string `json:"timezone,omitempty" doc:"Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format."`
|
||||
UserID *UUID `json:"userid,omitempty" doc:"User UUID, required for adding account from external provisioning system"`
|
||||
_ bool `name:"createUser" description:"Creates a user for an account that already exists"`
|
||||
}
|
||||
|
||||
func (CreateUser) response() interface{} {
|
||||
return new(User)
|
||||
}
|
||||
|
||||
// UpdateUser represents the modification of a User
|
||||
type UpdateUser struct {
|
||||
ID *UUID `json:"id" doc:"User uuid"`
|
||||
Email string `json:"email,omitempty" doc:"email"`
|
||||
FirstName string `json:"firstname,omitempty" doc:"first name"`
|
||||
LastName string `json:"lastname,omitempty" doc:"last name"`
|
||||
Password string `json:"password,omitempty" doc:"Clear text password (default hashed to SHA256SALT). If you wish to use any other hashing algorithm, you would need to write a custom authentication adapter"`
|
||||
Timezone string `json:"timezone,omitempty" doc:"Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format."`
|
||||
UserAPIKey string `json:"userapikey,omitempty" doc:"The API key for the user. Must be specified with userSecretKey"`
|
||||
UserName string `json:"username,omitempty" doc:"Unique username"`
|
||||
UserSecretKey string `json:"usersecretkey,omitempty" doc:"The secret key for the user. Must be specified with userApiKey"`
|
||||
_ bool `name:"updateUser" description:"Updates a user account"`
|
||||
}
|
||||
|
||||
func (UpdateUser) response() interface{} {
|
||||
return new(User)
|
||||
}
|
||||
//go:generate go run generate/main.go -interface=Listable ListUsers
|
||||
|
||||
// ListUsers represents the search for Users
|
||||
type ListUsers struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
AccountType int64 `json:"accounttype,omitempty" doc:"List users by account type. Valid types include admin, domain-admin, read-only-admin, or user."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ID *UUID `json:"id,omitempty" doc:"List user by ID."`
|
||||
IsRecursive bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
State string `json:"state,omitempty" doc:"List users by state of the user account."`
|
||||
Username string `json:"username,omitempty" doc:"List user by the username"`
|
||||
UserName string `json:"username,omitempty" doc:"List user by the username"`
|
||||
_ bool `name:"listUsers" description:"Lists user accounts"`
|
||||
}
|
||||
|
||||
|
@ -93,17 +61,3 @@ type ListUsersResponse struct {
|
|||
Count int `json:"count"`
|
||||
User []User `json:"user"`
|
||||
}
|
||||
|
||||
func (ListUsers) response() interface{} {
|
||||
return new(ListUsersResponse)
|
||||
}
|
||||
|
||||
// DeleteUser deletes a user for an account
|
||||
type DeleteUser struct {
|
||||
ID *UUID `json:"id" doc:"id of the user to be deleted"`
|
||||
_ bool `name:"deleteUser" description:"Deletes a user for an account"`
|
||||
}
|
||||
|
||||
func (DeleteUser) response() interface{} {
|
||||
return new(booleanResponse)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/users_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/users_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListUsers) Response() interface{} {
|
||||
return new(ListUsersResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListUsers) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListUsers) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListUsers) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListUsers) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListUsersResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListUsersResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.User {
|
||||
if !callback(&items.User[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
36
vendor/github.com/exoscale/egoscale/uuid.go
generated
vendored
36
vendor/github.com/exoscale/egoscale/uuid.go
generated
vendored
|
@ -4,7 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/satori/go.uuid"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// UUID holds a UUID v4
|
||||
|
@ -12,12 +12,36 @@ type UUID struct {
|
|||
uuid.UUID
|
||||
}
|
||||
|
||||
// Equal returns true if itself is equal to other
|
||||
// DeepCopy create a true copy of the receiver.
|
||||
func (u *UUID) DeepCopy() *UUID {
|
||||
if u == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := [uuid.Size]byte{}
|
||||
copy(out[:], u.Bytes())
|
||||
|
||||
return &UUID{
|
||||
(uuid.UUID)(out),
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto copies the receiver into out.
|
||||
//
|
||||
// In must be non nil.
|
||||
func (u *UUID) DeepCopyInto(out *UUID) {
|
||||
o := [uuid.Size]byte{}
|
||||
copy(o[:], u.Bytes())
|
||||
|
||||
out.UUID = (uuid.UUID)(o)
|
||||
}
|
||||
|
||||
// Equal returns true if itself is equal to other.
|
||||
func (u UUID) Equal(other UUID) bool {
|
||||
return uuid.Equal(u.UUID, other.UUID)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals the raw JSON into the MAC address
|
||||
// UnmarshalJSON unmarshals the raw JSON into the UUID.
|
||||
func (u *UUID) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
|
@ -31,12 +55,12 @@ func (u *UUID) UnmarshalJSON(b []byte) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// MarshalJSON converts the UUID to a string representation
|
||||
// MarshalJSON converts the UUID to a string representation.
|
||||
func (u UUID) MarshalJSON() ([]byte, error) {
|
||||
return []byte(fmt.Sprintf("%q", u.String())), nil
|
||||
}
|
||||
|
||||
// ParseUUID parses a string into a UUID
|
||||
// ParseUUID parses a string into a UUID.
|
||||
func ParseUUID(s string) (*UUID, error) {
|
||||
u, err := uuid.FromString(s)
|
||||
if err != nil {
|
||||
|
@ -45,7 +69,7 @@ func ParseUUID(s string) (*UUID, error) {
|
|||
return &UUID{u}, nil
|
||||
}
|
||||
|
||||
// MustParseUUID acts like ParseUUID but panic in case of a failure
|
||||
// MustParseUUID acts like ParseUUID but panic in case of a failure.
|
||||
func MustParseUUID(s string) *UUID {
|
||||
u, e := ParseUUID(s)
|
||||
if e != nil {
|
||||
|
|
2
vendor/github.com/exoscale/egoscale/version.go
generated
vendored
2
vendor/github.com/exoscale/egoscale/version.go
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
package egoscale
|
||||
|
||||
// Version of the library
|
||||
const Version = "0.11.6"
|
||||
const Version = "0.14.0"
|
||||
|
|
227
vendor/github.com/exoscale/egoscale/virtual_machines.go
generated
vendored
227
vendor/github.com/exoscale/egoscale/virtual_machines.go
generated
vendored
|
@ -29,8 +29,10 @@ const (
|
|||
VirtualMachineDestroyed VirtualMachineState = "Destroyed"
|
||||
// VirtualMachineExpunging "VM is being expunged
|
||||
VirtualMachineExpunging VirtualMachineState = "Expunging"
|
||||
// VirtualMachineMigrating VM is being migrated. host id holds to from host
|
||||
// VirtualMachineMigrating VM is being live migrated. host id holds destination host, last host id holds source host
|
||||
VirtualMachineMigrating VirtualMachineState = "Migrating"
|
||||
// VirtualMachineMoving VM is being migrated offline (volume is being moved).
|
||||
VirtualMachineMoving VirtualMachineState = "Moving"
|
||||
// VirtualMachineError VM is in error
|
||||
VirtualMachineError VirtualMachineState = "Error"
|
||||
// VirtualMachineUnknown VM state is unknown
|
||||
|
@ -60,19 +62,13 @@ type VirtualMachine struct {
|
|||
DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"the ID of the disk offering of the virtual machine"`
|
||||
DiskOfferingName string `json:"diskofferingname,omitempty" doc:"the name of the disk offering of the virtual machine"`
|
||||
DisplayName string `json:"displayname,omitempty" doc:"user generated name. The name of the virtual machine is returned if no displayname exists."`
|
||||
DisplayVM bool `json:"displayvm,omitempty" doc:"an optional field whether to the display the vm to the end user or not."`
|
||||
Domain string `json:"domain,omitempty" doc:"the name of the domain in which the virtual machine exists"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the ID of the domain in which the virtual machine exists"`
|
||||
ForVirtualNetwork bool `json:"forvirtualnetwork,omitempty" doc:"the virtual network for the service offering"`
|
||||
Group string `json:"group,omitempty" doc:"the group name of the virtual machine"`
|
||||
GroupID *UUID `json:"groupid,omitempty" doc:"the group ID of the virtual machine"`
|
||||
HAEnable bool `json:"haenable,omitempty" doc:"true if high-availability is enabled, false otherwise"`
|
||||
HostID *UUID `json:"hostid,omitempty" doc:"the ID of the host for the virtual machine"`
|
||||
HostName string `json:"hostname,omitempty" doc:"the name of the host for the virtual machine"`
|
||||
Hypervisor string `json:"hypervisor,omitempty" doc:"the hypervisor on which the template runs"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the ID of the virtual machine"`
|
||||
InstanceName string `json:"instancename,omitempty" doc:"instance name of the user vm; this parameter is returned to the ROOT admin only"`
|
||||
IsDynamicallyScalable bool `json:"isdynamicallyscalable,omitempty" doc:"true if vm contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory."`
|
||||
IsoDisplayText string `json:"isodisplaytext,omitempty" doc:"an alternate display text of the ISO attached to the virtual machine"`
|
||||
IsoID *UUID `json:"isoid,omitempty" doc:"the ID of the ISO attached to the virtual machine"`
|
||||
IsoName string `json:"isoname,omitempty" doc:"the name of the ISO attached to the virtual machine"`
|
||||
|
@ -84,6 +80,7 @@ type VirtualMachine struct {
|
|||
Nic []Nic `json:"nic,omitempty" doc:"the list of nics associated with vm"`
|
||||
OSCategoryID *UUID `json:"oscategoryid,omitempty" doc:"Os category ID of the virtual machine"`
|
||||
OSCategoryName string `json:"oscategoryname,omitempty" doc:"Os category name of the virtual machine"`
|
||||
OSTypeID *UUID `json:"ostypeid,omitempty" doc:"OS type id of the vm"`
|
||||
Password string `json:"password,omitempty" doc:"the password (if exists) of the virtual machine"`
|
||||
PasswordEnabled bool `json:"passwordenabled,omitempty" doc:"true if the password rest feature is enabled, false otherwise"`
|
||||
PCIDevices []PCIDevice `json:"pcidevices,omitempty" doc:"list of PCI devices"`
|
||||
|
@ -122,11 +119,9 @@ func (vm VirtualMachine) Delete(ctx context.Context, client *Client) error {
|
|||
|
||||
// ListRequest builds the ListVirtualMachines request
|
||||
func (vm VirtualMachine) ListRequest() (ListCommand, error) {
|
||||
// XXX: AffinityGroupID, SecurityGroupID, Tags
|
||||
// XXX: AffinityGroupID, SecurityGroupID
|
||||
|
||||
req := &ListVirtualMachines{
|
||||
Account: vm.Account,
|
||||
DomainID: vm.DomainID,
|
||||
GroupID: vm.GroupID,
|
||||
ID: vm.ID,
|
||||
Name: vm.Name,
|
||||
|
@ -140,14 +135,18 @@ func (vm VirtualMachine) ListRequest() (ListCommand, error) {
|
|||
req.IPAddress = nic.IPAddress
|
||||
}
|
||||
|
||||
for i := range vm.Tags {
|
||||
req.Tags = append(req.Tags, vm.Tags[i])
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// DefaultNic returns the default nic
|
||||
func (vm VirtualMachine) DefaultNic() *Nic {
|
||||
for _, nic := range vm.Nic {
|
||||
for i, nic := range vm.Nic {
|
||||
if nic.IsDefault {
|
||||
return &nic
|
||||
return &vm.Nic[i]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,8 +170,9 @@ func (vm VirtualMachine) NicsByType(nicType string) []Nic {
|
|||
for _, nic := range vm.Nic {
|
||||
if nic.Type == nicType {
|
||||
// XXX The API forgets to specify it
|
||||
nic.VirtualMachineID = vm.ID
|
||||
nics = append(nics, nic)
|
||||
n := nic
|
||||
n.VirtualMachineID = vm.ID
|
||||
nics = append(nics, n)
|
||||
}
|
||||
}
|
||||
return nics
|
||||
|
@ -184,8 +184,9 @@ func (vm VirtualMachine) NicsByType(nicType string) []Nic {
|
|||
func (vm VirtualMachine) NicByNetworkID(networkID UUID) *Nic {
|
||||
for _, nic := range vm.Nic {
|
||||
if nic.NetworkID.Equal(networkID) {
|
||||
nic.VirtualMachineID = vm.ID
|
||||
return &nic
|
||||
n := nic
|
||||
n.VirtualMachineID = vm.ID
|
||||
return &n
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -195,8 +196,9 @@ func (vm VirtualMachine) NicByNetworkID(networkID UUID) *Nic {
|
|||
func (vm VirtualMachine) NicByID(nicID UUID) *Nic {
|
||||
for _, nic := range vm.Nic {
|
||||
if nic.ID.Equal(nicID) {
|
||||
nic.VirtualMachineID = vm.ID
|
||||
return &nic
|
||||
n := nic
|
||||
n.VirtualMachineID = vm.ID
|
||||
return &n
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,10 +215,10 @@ type IPToNetwork struct {
|
|||
// PCIDevice represents a PCI card present in the host
|
||||
type PCIDevice struct {
|
||||
PCIVendorName string `json:"pcivendorname,omitempty" doc:"Device vendor name of pci card"`
|
||||
DeviceID *UUID `json:"deviceid,omitempty" doc:"Device model ID of pci card"`
|
||||
DeviceID string `json:"deviceid,omitempty" doc:"Device model ID of pci card"`
|
||||
RemainingCapacity int `json:"remainingcapacity,omitempty" doc:"Remaining capacity in terms of no. of more VMs that can be deployped with this vGPU type"`
|
||||
MaxCapacity int `json:"maxcapacity,omitempty" doc:"Maximum vgpu can be created with this vgpu type on the given pci group"`
|
||||
PCIVendorID *UUID `json:"pcivendorid,omitempty" doc:"Device vendor ID of pci card"`
|
||||
PCIVendorID string `json:"pcivendorid,omitempty" doc:"Device vendor ID of pci card"`
|
||||
PCIDeviceName string `json:"pcidevicename,omitempty" doc:"Device model name of pci card"`
|
||||
}
|
||||
|
||||
|
@ -229,8 +231,8 @@ type Password struct {
|
|||
|
||||
// VirtualMachineUserData represents the base64 encoded user-data
|
||||
type VirtualMachineUserData struct {
|
||||
UserData string `json:"userdata,omitempty" doc:"Base 64 encoded VM user data"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"the ID of the virtual machine"`
|
||||
UserData string `json:"userdata" doc:"Base 64 encoded VM user data"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid" doc:"the ID of the virtual machine"`
|
||||
}
|
||||
|
||||
// Decode decodes as a readable string the content of the user-data (base64 · gzip)
|
||||
|
@ -260,24 +262,16 @@ func (userdata VirtualMachineUserData) Decode() (string, error) {
|
|||
//
|
||||
// Regarding the UserData field, the client is responsible to base64 (and probably gzip) it. Doing it within this library would make the integration with other tools, e.g. Terraform harder.
|
||||
type DeployVirtualMachine struct {
|
||||
Account string `json:"account,omitempty" doc:"an optional account for the virtual machine. Must be used with domainId."`
|
||||
AffinityGroupIDs []UUID `json:"affinitygroupids,omitempty" doc:"comma separated list of affinity groups id that are going to be applied to the virtual machine. Mutually exclusive with affinitygroupnames parameter"`
|
||||
AffinityGroupNames []string `json:"affinitygroupnames,omitempty" doc:"comma separated list of affinity groups names that are going to be applied to the virtual machine.Mutually exclusive with affinitygroupids parameter"`
|
||||
CustomID *UUID `json:"customid,omitempty" doc:"an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only"`
|
||||
DeploymentPlanner string `json:"deploymentplanner,omitempty" doc:"Deployment planner to use for vm allocation. Available to ROOT admin only"`
|
||||
Details map[string]string `json:"details,omitempty" doc:"used to specify the custom parameters."`
|
||||
DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"the ID of the disk offering for the virtual machine. If the template is of ISO format, the diskOfferingId is for the root disk volume. Otherwise this parameter is used to indicate the offering for the data disk volume. If the templateId parameter passed is from a Template object, the diskOfferingId refers to a DATA Disk Volume created. If the templateId parameter passed is from an ISO object, the diskOfferingId refers to a ROOT Disk Volume created."`
|
||||
DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"the ID of the disk offering for the virtual machine. If the template is of ISO format, the diskofferingid is for the root disk volume. Otherwise this parameter is used to indicate the offering for the data disk volume. If the templateid parameter passed is from a Template object, the diskofferingid refers to a DATA Disk Volume created. If the templateid parameter passed is from an ISO object, the diskofferingid refers to a ROOT Disk Volume created."`
|
||||
DisplayName string `json:"displayname,omitempty" doc:"an optional user generated name for the virtual machine"`
|
||||
DisplayVM *bool `json:"displayvm,omitempty" doc:"an optional field, whether to the display the vm to the end user or not."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used."`
|
||||
Group string `json:"group,omitempty" doc:"an optional group for the virtual machine"`
|
||||
HostID *UUID `json:"hostid,omitempty" doc:"destination Host ID to deploy the VM to - parameter available for root admin only"`
|
||||
Hypervisor string `json:"hypervisor,omitempty" doc:"the hypervisor on which to deploy the virtual machine"`
|
||||
IP4 *bool `json:"ip4,omitempty" doc:"True to set an IPv4 to the default interface"`
|
||||
IP6 *bool `json:"ip6,omitempty" doc:"True to set an IPv6 to the default interface"`
|
||||
IP6Address net.IP `json:"ip6address,omitempty" doc:"the ipv6 address for default vm's network"`
|
||||
IPAddress net.IP `json:"ipaddress,omitempty" doc:"the ip address for default vm's network"`
|
||||
IPToNetworkList []IPToNetwork `json:"iptonetworklist,omitempty" doc:"ip to network mapping. Can't be specified with networkIds parameter. Example: iptonetworklist[0].ip=10.10.10.11&iptonetworklist[0].ipv6=fc00:1234:5678::abcd&iptonetworklist[0].networkid=uuid - requests to use ip 10.10.10.11 in network id=uuid"`
|
||||
Keyboard string `json:"keyboard,omitempty" doc:"an optional keyboard device type for the virtual machine. valid value can be one of de,de-ch,es,fi,fr,fr-be,fr-ch,is,it,jp,nl-be,no,pt,uk,us"`
|
||||
KeyPair string `json:"keypair,omitempty" doc:"name of the ssh key pair used to login to the virtual machine"`
|
||||
Name string `json:"name,omitempty" doc:"host name for the virtual machine"`
|
||||
|
@ -286,7 +280,7 @@ type DeployVirtualMachine struct {
|
|||
SecurityGroupIDs []UUID `json:"securitygroupids,omitempty" doc:"comma separated list of security groups id that going to be applied to the virtual machine. Should be passed only when vm is created from a zone with Basic Network support. Mutually exclusive with securitygroupnames parameter"`
|
||||
SecurityGroupNames []string `json:"securitygroupnames,omitempty" doc:"comma separated list of security groups names that going to be applied to the virtual machine. Should be passed only when vm is created from a zone with Basic Network support. Mutually exclusive with securitygroupids parameter"`
|
||||
ServiceOfferingID *UUID `json:"serviceofferingid" doc:"the ID of the service offering for the virtual machine"`
|
||||
Size int64 `json:"size,omitempty" doc:"the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId"`
|
||||
Size int64 `json:"size,omitempty" doc:"the arbitrary size for the DATADISK volume. Mutually exclusive with diskofferingid"`
|
||||
StartVM *bool `json:"startvm,omitempty" doc:"true if start vm after creating. Default value is true"`
|
||||
TemplateID *UUID `json:"templateid" doc:"the ID of the template for the virtual machine"`
|
||||
UserData string `json:"userdata,omitempty" doc:"an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding."`
|
||||
|
@ -294,7 +288,7 @@ type DeployVirtualMachine struct {
|
|||
_ bool `name:"deployVirtualMachine" description:"Creates and automatically starts a virtual machine based on a service offering, disk offering, and template."`
|
||||
}
|
||||
|
||||
func (req DeployVirtualMachine) onBeforeSend(params url.Values) error {
|
||||
func (req DeployVirtualMachine) onBeforeSend(_ url.Values) error {
|
||||
// Either AffinityGroupIDs or AffinityGroupNames must be set
|
||||
if len(req.AffinityGroupIDs) > 0 && len(req.AffinityGroupNames) > 0 {
|
||||
return fmt.Errorf("either AffinityGroupIDs or AffinityGroupNames must be set")
|
||||
|
@ -308,27 +302,29 @@ func (req DeployVirtualMachine) onBeforeSend(params url.Values) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (DeployVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (DeployVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (DeployVirtualMachine) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (DeployVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
// StartVirtualMachine (Async) represents the creation of the virtual machine
|
||||
type StartVirtualMachine struct {
|
||||
ID *UUID `json:"id" doc:"The ID of the virtual machine"`
|
||||
DeploymentPlanner string `json:"deploymentplanner,omitempty" doc:"Deployment planner to use for vm allocation. Available to ROOT admin only"`
|
||||
HostID *UUID `json:"hostid,omitempty" doc:"destination Host ID to deploy the VM to - parameter available for root admin only"`
|
||||
_ bool `name:"startVirtualMachine" description:"Starts a virtual machine."`
|
||||
}
|
||||
|
||||
func (StartVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (StartVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (StartVirtualMachine) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (StartVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -339,11 +335,13 @@ type StopVirtualMachine struct {
|
|||
_ bool `name:"stopVirtualMachine" description:"Stops a virtual machine."`
|
||||
}
|
||||
|
||||
func (StopVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (StopVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (StopVirtualMachine) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (StopVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -353,11 +351,13 @@ type RebootVirtualMachine struct {
|
|||
_ bool `name:"rebootVirtualMachine" description:"Reboots a virtual machine."`
|
||||
}
|
||||
|
||||
func (RebootVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RebootVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (RebootVirtualMachine) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (RebootVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -369,11 +369,13 @@ type RestoreVirtualMachine struct {
|
|||
_ bool `name:"restoreVirtualMachine" description:"Restore a VM to original template/ISO or new template/ISO"`
|
||||
}
|
||||
|
||||
func (RestoreVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RestoreVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (RestoreVirtualMachine) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (RestoreVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -383,42 +385,41 @@ type RecoverVirtualMachine struct {
|
|||
_ bool `name:"recoverVirtualMachine" description:"Recovers a virtual machine."`
|
||||
}
|
||||
|
||||
func (RecoverVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RecoverVirtualMachine) Response() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
// DestroyVirtualMachine (Async) represents the destruction of the virtual machine
|
||||
type DestroyVirtualMachine struct {
|
||||
ID *UUID `json:"id" doc:"The ID of the virtual machine"`
|
||||
Expunge *bool `json:"expunge,omitempty" doc:"If true is passed, the vm is expunged immediately. False by default."`
|
||||
_ bool `name:"destroyVirtualMachine" description:"Destroys a virtual machine."`
|
||||
}
|
||||
|
||||
func (DestroyVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (DestroyVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (DestroyVirtualMachine) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (DestroyVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
// UpdateVirtualMachine represents the update of the virtual machine
|
||||
type UpdateVirtualMachine struct {
|
||||
ID *UUID `json:"id" doc:"The ID of the virtual machine"`
|
||||
CustomID *UUID `json:"customid,omitempty" doc:"an optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only"`
|
||||
Details map[string]string `json:"details,omitempty" doc:"Details in key/value pairs."`
|
||||
DisplayName string `json:"displayname,omitempty" doc:"user generated name"`
|
||||
DisplayVM *bool `json:"displayvm,omitempty" doc:"an optional field, whether to the display the vm to the end user or not."`
|
||||
Group string `json:"group,omitempty" doc:"group of the virtual machine"`
|
||||
HAEnable *bool `json:"haenable,omitempty" doc:"true if high-availability is enabled for the virtual machine, false otherwise"`
|
||||
IsDynamicallyScalable *bool `json:"isdynamicallyscalable,omitempty" doc:"true if VM contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory"`
|
||||
Name string `json:"name,omitempty" doc:"new host name of the vm. The VM has to be stopped/started for this update to take affect"`
|
||||
SecurityGroupIDs []UUID `json:"securitygroupids,omitempty" doc:"list of security group ids to be applied on the virtual machine."`
|
||||
UserData string `json:"userdata,omitempty" doc:"an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding."`
|
||||
_ bool `name:"updateVirtualMachine" description:"Updates properties of a virtual machine. The VM has to be stopped and restarted for the new properties to take effect. UpdateVirtualMachine does not first check whether the VM is stopped. Therefore, stop the VM manually before issuing this call."`
|
||||
}
|
||||
|
||||
func (UpdateVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (UpdateVirtualMachine) Response() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -428,12 +429,14 @@ type ExpungeVirtualMachine struct {
|
|||
_ bool `name:"expungeVirtualMachine" description:"Expunge a virtual machine. Once expunged, it cannot be recoverd."`
|
||||
}
|
||||
|
||||
func (ExpungeVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (ExpungeVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (ExpungeVirtualMachine) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (ExpungeVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// ScaleVirtualMachine (Async) scales the virtual machine to a new service offering.
|
||||
|
@ -447,12 +450,14 @@ type ScaleVirtualMachine struct {
|
|||
_ bool `name:"scaleVirtualMachine" description:"Scales the virtual machine to a new service offering."`
|
||||
}
|
||||
|
||||
func (ScaleVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (ScaleVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (ScaleVirtualMachine) asyncResponse() interface{} {
|
||||
return new(booleanResponse)
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (ScaleVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(BooleanResponse)
|
||||
}
|
||||
|
||||
// ChangeServiceForVirtualMachine changes the service offering for a virtual machine. The virtual machine must be in a "Stopped" state for this command to take effect.
|
||||
|
@ -463,7 +468,8 @@ type ChangeServiceForVirtualMachine struct {
|
|||
_ bool `name:"changeServiceForVirtualMachine" description:"Changes the service offering for a virtual machine. The virtual machine must be in a \"Stopped\" state for this command to take effect."`
|
||||
}
|
||||
|
||||
func (ChangeServiceForVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (ChangeServiceForVirtualMachine) Response() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -473,10 +479,13 @@ type ResetPasswordForVirtualMachine struct {
|
|||
_ bool `name:"resetPasswordForVirtualMachine" description:"Resets the password for virtual machine. The virtual machine must be in a \"Stopped\" state and the template must already support this feature for this command to take effect."`
|
||||
}
|
||||
|
||||
func (ResetPasswordForVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (ResetPasswordForVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
func (ResetPasswordForVirtualMachine) asyncResponse() interface{} {
|
||||
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (ResetPasswordForVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -486,28 +495,24 @@ type GetVMPassword struct {
|
|||
_ bool `name:"getVMPassword" description:"Returns an encrypted password for the VM"`
|
||||
}
|
||||
|
||||
func (GetVMPassword) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (GetVMPassword) Response() interface{} {
|
||||
return new(Password)
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListVirtualMachines
|
||||
|
||||
// ListVirtualMachines represents a search for a VM
|
||||
type ListVirtualMachines struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
AffinityGroupID *UUID `json:"affinitygroupid,omitempty" doc:"list vms by affinity group"`
|
||||
Details []string `json:"details,omitempty" doc:"comma separated list of host details requested, value can be a list of [all, group, nics, stats, secgrp, tmpl, servoff, diskoff, iso, volume, min, affgrp]. If no parameter is passed in, the details will be defaulted to all"`
|
||||
DisplayVM *bool `json:"displayvm,omitempty" doc:"list resources by display flag; only ROOT admin is eligible to pass this parameter"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ForVirtualNetwork *bool `json:"forvirtualnetwork,omitempty" doc:"list by network type; true if need to list vms using Virtual Network, false otherwise"`
|
||||
GroupID *UUID `json:"groupid,omitempty" doc:"the group ID"`
|
||||
HostID *UUID `json:"hostid,omitempty" doc:"the host ID"`
|
||||
Hypervisor string `json:"hypervisor,omitempty" doc:"the target hypervisor for the template"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the ID of the virtual machine"`
|
||||
IDs []string `json:"ids,omitempty" doc:"the IDs of the virtual machines, mutually exclusive with id"`
|
||||
IPAddress net.IP `json:"ipaddress,omitempty" doc:"an IP address to filter the result"`
|
||||
IsoID *UUID `json:"isoid,omitempty" doc:"list vms by iso"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Name string `json:"name,omitempty" doc:"name of the virtual machine"`
|
||||
NetworkID *UUID `json:"networkid,omitempty" doc:"list by network id"`
|
||||
Page int `json:"page,omitempty"`
|
||||
|
@ -526,47 +531,21 @@ type ListVirtualMachinesResponse struct {
|
|||
VirtualMachine []VirtualMachine `json:"virtualmachine"`
|
||||
}
|
||||
|
||||
func (ListVirtualMachines) response() interface{} {
|
||||
return new(ListVirtualMachinesResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (ls *ListVirtualMachines) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListVirtualMachines) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListVirtualMachines) each(resp interface{}, callback IterateItemFunc) {
|
||||
vms, ok := resp.(*ListVirtualMachinesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type. ListVirtualMachinesResponse expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range vms.VirtualMachine {
|
||||
if !callback(&vms.VirtualMachine[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddNicToVirtualMachine (Async) adds a NIC to a VM
|
||||
type AddNicToVirtualMachine struct {
|
||||
NetworkID *UUID `json:"networkid" doc:"Network ID"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid" doc:"Virtual Machine ID"`
|
||||
IPAddress net.IP `json:"ipaddress,omitempty" doc:"IP Address for the new network"`
|
||||
IPAddress net.IP `json:"ipaddress,omitempty" doc:"Static IP address lease for the corresponding NIC and network which should be in the range defined in the network"`
|
||||
_ bool `name:"addNicToVirtualMachine" description:"Adds VM to specified network by creating a NIC"`
|
||||
}
|
||||
|
||||
func (AddNicToVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (AddNicToVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (AddNicToVirtualMachine) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (AddNicToVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -577,11 +556,13 @@ type RemoveNicFromVirtualMachine struct {
|
|||
_ bool `name:"removeNicFromVirtualMachine" description:"Removes VM from specified network by deleting a NIC"`
|
||||
}
|
||||
|
||||
func (RemoveNicFromVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (RemoveNicFromVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (RemoveNicFromVirtualMachine) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (RemoveNicFromVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -592,10 +573,13 @@ type UpdateDefaultNicForVirtualMachine struct {
|
|||
_ bool `name:"updateDefaultNicForVirtualMachine" description:"Changes the default NIC on a VM"`
|
||||
}
|
||||
|
||||
func (UpdateDefaultNicForVirtualMachine) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (UpdateDefaultNicForVirtualMachine) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
func (UpdateDefaultNicForVirtualMachine) asyncResponse() interface{} {
|
||||
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (UpdateDefaultNicForVirtualMachine) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
|
@ -605,35 +589,24 @@ type GetVirtualMachineUserData struct {
|
|||
_ bool `name:"getVirtualMachineUserData" description:"Returns user data associated with the VM"`
|
||||
}
|
||||
|
||||
func (GetVirtualMachineUserData) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (GetVirtualMachineUserData) Response() interface{} {
|
||||
return new(VirtualMachineUserData)
|
||||
}
|
||||
|
||||
// Decode decodes the base64 / gzipped encoded user data
|
||||
|
||||
// MigrateVirtualMachine (Async) attempts migration of a VM to a different host or Root volume of the vm to a different storage pool
|
||||
type MigrateVirtualMachine struct {
|
||||
HostID *UUID `json:"hostid,omitempty" doc:"Destination Host ID to migrate VM to. Required for live migrating a VM from host to host"`
|
||||
StorageID *UUID `json:"storageid,omitempty" doc:"Destination storage pool ID to migrate VM volumes to. Required for migrating the root disk volume"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid" doc:"the ID of the virtual machine"`
|
||||
_ bool `name:"migrateVirtualMachine" description:"Attempts Migration of a VM to a different host or Root volume of the vm to a different storage pool"`
|
||||
}
|
||||
|
||||
func (MigrateVirtualMachine) response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (MigrateVirtualMachine) asyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
||||
// UpdateVMNicIP updates the default IP address of a VM Nic
|
||||
type UpdateVMNicIP struct {
|
||||
_ bool `name:"updateVmNicIp" description:"Update the default Ip of a VM Nic"`
|
||||
IPAddress net.IP `json:"ipaddress" doc:"Static IP address lease for the corresponding NIC and network which should be in the range defined in the network. Also, the last IP of the network is reserved by the DHCP server."`
|
||||
IPAddress net.IP `json:"ipaddress,omitempty" doc:"Static IP address lease for the corresponding NIC and network which should be in the range defined in the network. If absent, the call removes the lease associated with the nic."`
|
||||
NicID *UUID `json:"nicid" doc:"the ID of the nic."`
|
||||
}
|
||||
|
||||
func (UpdateVMNicIP) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (UpdateVMNicIP) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (UpdateVMNicIP) AsyncResponse() interface{} {
|
||||
return new(VirtualMachine)
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/virtualmachines_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/virtualmachines_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListVirtualMachines) Response() interface{} {
|
||||
return new(ListVirtualMachinesResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListVirtualMachines) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListVirtualMachines) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListVirtualMachines) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListVirtualMachines) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListVirtualMachinesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListVirtualMachinesResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.VirtualMachine {
|
||||
if !callback(&items.VirtualMachine[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
68
vendor/github.com/exoscale/egoscale/vm_groups.go
generated
vendored
68
vendor/github.com/exoscale/egoscale/vm_groups.go
generated
vendored
|
@ -1,68 +0,0 @@
|
|||
package egoscale
|
||||
|
||||
// InstanceGroup represents a group of VM
|
||||
type InstanceGroup struct {
|
||||
Account string `json:"account,omitempty" doc:"the account owning the instance group"`
|
||||
Created string `json:"created,omitempty" doc:"time and date the instance group was created"`
|
||||
Domain string `json:"domain,omitempty" doc:"the domain name of the instance group"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain ID of the instance group"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the id of the instance group"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the instance group"`
|
||||
}
|
||||
|
||||
// CreateInstanceGroup creates a VM group
|
||||
type CreateInstanceGroup struct {
|
||||
Name string `json:"name" doc:"the name of the instance group"`
|
||||
Account string `json:"account,omitempty" doc:"the account of the instance group. The account parameter must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the domain ID of account owning the instance group"`
|
||||
_ bool `name:"createInstanceGroup" description:"Creates a vm group"`
|
||||
}
|
||||
|
||||
func (CreateInstanceGroup) response() interface{} {
|
||||
return new(InstanceGroup)
|
||||
}
|
||||
|
||||
// UpdateInstanceGroup updates a VM group
|
||||
type UpdateInstanceGroup struct {
|
||||
ID *UUID `json:"id" doc:"Instance group ID"`
|
||||
Name string `json:"name,omitempty" doc:"new instance group name"`
|
||||
_ bool `name:"updateInstanceGroup" description:"Updates a vm group"`
|
||||
}
|
||||
|
||||
func (UpdateInstanceGroup) response() interface{} {
|
||||
return new(InstanceGroup)
|
||||
}
|
||||
|
||||
// DeleteInstanceGroup deletes a VM group
|
||||
type DeleteInstanceGroup struct {
|
||||
ID *UUID `json:"id" doc:"the ID of the instance group"`
|
||||
_ bool `name:"deleteInstanceGroup" description:"Deletes a vm group"`
|
||||
}
|
||||
|
||||
func (DeleteInstanceGroup) response() interface{} {
|
||||
return new(booleanResponse)
|
||||
}
|
||||
|
||||
// ListInstanceGroups lists VM groups
|
||||
type ListInstanceGroups struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
ID *UUID `json:"id,omitempty" doc:"list instance groups by ID"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Name string `json:"name,omitempty" doc:"list instance groups by name"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
_ bool `name:"listInstanceGroups" description:"Lists vm groups"`
|
||||
}
|
||||
|
||||
// ListInstanceGroupsResponse represents a list of instance groups
|
||||
type ListInstanceGroupsResponse struct {
|
||||
Count int `json:"count"`
|
||||
InstanceGroup []InstanceGroup `json:"instancegroup"`
|
||||
}
|
||||
|
||||
func (ListInstanceGroups) response() interface{} {
|
||||
return new(ListInstanceGroupsResponse)
|
||||
}
|
69
vendor/github.com/exoscale/egoscale/volumes.go
generated
vendored
69
vendor/github.com/exoscale/egoscale/volumes.go
generated
vendored
|
@ -1,9 +1,5 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Volume represents a volume linked to a VM
|
||||
type Volume struct {
|
||||
Account string `json:"account,omitempty" doc:"the account associated with the disk volume"`
|
||||
|
@ -22,8 +18,6 @@ type Volume struct {
|
|||
DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"ID of the disk offering"`
|
||||
DiskOfferingName string `json:"diskofferingname,omitempty" doc:"name of the disk offering"`
|
||||
DisplayVolume bool `json:"displayvolume,omitempty" doc:"an optional field whether to the display the volume to the end user or not."`
|
||||
Domain string `json:"domain,omitempty" doc:"the domain associated with the disk volume"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the ID of the domain associated with the disk volume"`
|
||||
Hypervisor string `json:"hypervisor,omitempty" doc:"Hypervisor the volume belongs to"`
|
||||
ID *UUID `json:"id,omitempty" doc:"ID of the disk volume"`
|
||||
IsExtractable *bool `json:"isextractable,omitempty" doc:"true if the volume is extractable, false otherwise"`
|
||||
|
@ -49,7 +43,7 @@ type Volume struct {
|
|||
StorageType string `json:"storagetype,omitempty" doc:"shared or local storage"`
|
||||
Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with volume"`
|
||||
TemplateDisplayText string `json:"templatedisplaytext,omitempty" doc:"an alternate display text of the template for the virtual machine"`
|
||||
TemplateID string `json:"templateid,omitempty" doc:"the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file."` // no *UUID because of the -1 thingy...
|
||||
TemplateID *UUID `json:"templateid,omitempty" doc:"the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file."` // no *UUID because of the -1 thingy...
|
||||
TemplateName string `json:"templatename,omitempty" doc:"the name of the template for the virtual machine"`
|
||||
Type string `json:"type,omitempty" doc:"type of the disk volume (ROOT or DATADISK)"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"id of the virtual machine"`
|
||||
|
@ -68,8 +62,6 @@ func (Volume) ResourceType() string {
|
|||
// ListRequest builds the ListVolumes request
|
||||
func (vol Volume) ListRequest() (ListCommand, error) {
|
||||
req := &ListVolumes{
|
||||
Account: vol.Account,
|
||||
DomainID: vol.DomainID,
|
||||
Name: vol.Name,
|
||||
Type: vol.Type,
|
||||
VirtualMachineID: vol.VirtualMachineID,
|
||||
|
@ -83,39 +75,34 @@ func (vol Volume) ListRequest() (ListCommand, error) {
|
|||
type ResizeVolume struct {
|
||||
ID *UUID `json:"id" doc:"the ID of the disk volume"`
|
||||
DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"new disk offering id"`
|
||||
ShrinkOk *bool `json:"shrinkok,omitempty" doc:"Verify OK to Shrink"`
|
||||
Size int64 `json:"size,omitempty" doc:"New volume size in G"`
|
||||
Size int64 `json:"size,omitempty" doc:"New volume size in G (must be larger than current size since shrinking the disk is not supported)"`
|
||||
_ bool `name:"resizeVolume" description:"Resizes a volume"`
|
||||
}
|
||||
|
||||
func (ResizeVolume) response() interface{} {
|
||||
// Response returns the struct to unmarshal
|
||||
func (ResizeVolume) Response() interface{} {
|
||||
return new(AsyncJobResult)
|
||||
}
|
||||
|
||||
func (ResizeVolume) asyncResponse() interface{} {
|
||||
// AsyncResponse returns the struct to unmarshal the async job
|
||||
func (ResizeVolume) AsyncResponse() interface{} {
|
||||
return new(Volume)
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListVolumes
|
||||
|
||||
// ListVolumes represents a query listing volumes
|
||||
type ListVolumes struct {
|
||||
Account string `json:"account,omitempty" doc:"list resources by account. Must be used with the domainId parameter."`
|
||||
DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"list volumes by disk offering"`
|
||||
DisplayVolume *bool `json:"displayvolume,omitempty" doc:"list resources by display flag; only ROOT admin is eligible to pass this parameter"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"list only resources belonging to the domain specified"`
|
||||
HostID *UUID `json:"hostid,omitempty" doc:"list volumes on specified host"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the ID of the disk volume"`
|
||||
IsRecursive *bool `json:"isrecursive,omitempty" doc:"defaults to false, but if true, lists all resources from the parent specified by the domainId till leaves."`
|
||||
DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"List volumes by disk offering"`
|
||||
ID *UUID `json:"id,omitempty" doc:"The ID of the disk volume"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
ListAll *bool `json:"listall,omitempty" doc:"If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the disk volume"`
|
||||
Name string `json:"name,omitempty" doc:"The name of the disk volume"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
PodID *UUID `json:"podid,omitempty" doc:"the pod id the disk volume belongs to"`
|
||||
StorageID *UUID `json:"storageid,omitempty" doc:"the ID of the storage pool, available to ROOT admin only"`
|
||||
Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"`
|
||||
Type string `json:"type,omitempty" doc:"the type of disk volume"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"the ID of the virtual machine"`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"the ID of the availability zone"`
|
||||
Type string `json:"type,omitempty" doc:"The type of disk volume"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"The ID of the virtual machine"`
|
||||
ZoneID *UUID `json:"zoneid,omitempty" doc:"The ID of the availability zone"`
|
||||
_ bool `name:"listVolumes" description:"Lists all volumes."`
|
||||
}
|
||||
|
||||
|
@ -124,31 +111,3 @@ type ListVolumesResponse struct {
|
|||
Count int `json:"count"`
|
||||
Volume []Volume `json:"volume"`
|
||||
}
|
||||
|
||||
func (ListVolumes) response() interface{} {
|
||||
return new(ListVolumesResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (ls *ListVolumes) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListVolumes) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListVolumes) each(resp interface{}, callback IterateItemFunc) {
|
||||
volumes, ok := resp.(*ListVolumesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type. ListVolumesResponse expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range volumes.Volume {
|
||||
if !callback(&volumes.Volume[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/volumes_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/volumes_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListVolumes) Response() interface{} {
|
||||
return new(ListVolumesResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListVolumes) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListVolumes) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListVolumes) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListVolumes) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListVolumesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListVolumesResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.Volume {
|
||||
if !callback(&items.Volume[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
36
vendor/github.com/exoscale/egoscale/zones.go
generated
vendored
36
vendor/github.com/exoscale/egoscale/zones.go
generated
vendored
|
@ -1,7 +1,6 @@
|
|||
package egoscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
|
@ -15,9 +14,6 @@ type Zone struct {
|
|||
DisplayText string `json:"displaytext,omitempty" doc:"the display text of the zone"`
|
||||
DNS1 net.IP `json:"dns1,omitempty" doc:"the first DNS for the Zone"`
|
||||
DNS2 net.IP `json:"dns2,omitempty" doc:"the second DNS for the Zone"`
|
||||
Domain string `json:"domain,omitempty" doc:"Network domain name for the networks in the zone"`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the UUID of the containing domain, null for public zones"`
|
||||
DomainName string `json:"domainname,omitempty" doc:"the name of the containing domain, null for public zones"`
|
||||
GuestCIDRAddress *CIDR `json:"guestcidraddress,omitempty" doc:"the guest CIDR address for the Zone"`
|
||||
ID *UUID `json:"id,omitempty" doc:"Zone id"`
|
||||
InternalDNS1 net.IP `json:"internaldns1,omitempty" doc:"the first internal DNS for the Zone"`
|
||||
|
@ -37,7 +33,6 @@ type Zone struct {
|
|||
// ListRequest builds the ListZones request
|
||||
func (zone Zone) ListRequest() (ListCommand, error) {
|
||||
req := &ListZones{
|
||||
DomainID: zone.DomainID,
|
||||
ID: zone.ID,
|
||||
Name: zone.Name,
|
||||
}
|
||||
|
@ -45,10 +40,11 @@ func (zone Zone) ListRequest() (ListCommand, error) {
|
|||
return req, nil
|
||||
}
|
||||
|
||||
//go:generate go run generate/main.go -interface=Listable ListZones
|
||||
|
||||
// ListZones represents a query for zones
|
||||
type ListZones struct {
|
||||
Available *bool `json:"available,omitempty" doc:"true if you want to retrieve all available Zones. False if you only want to return the Zones from which you have at least one VM. Default is false."`
|
||||
DomainID *UUID `json:"domainid,omitempty" doc:"the ID of the domain associated with the zone"`
|
||||
ID *UUID `json:"id,omitempty" doc:"the ID of the zone"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the zone"`
|
||||
|
@ -64,31 +60,3 @@ type ListZonesResponse struct {
|
|||
Count int `json:"count"`
|
||||
Zone []Zone `json:"zone"`
|
||||
}
|
||||
|
||||
func (ListZones) response() interface{} {
|
||||
return new(ListZonesResponse)
|
||||
}
|
||||
|
||||
// SetPage sets the current page
|
||||
func (ls *ListZones) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListZones) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
func (ListZones) each(resp interface{}, callback IterateItemFunc) {
|
||||
zones, ok := resp.(*ListZonesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type. ListZonesResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range zones.Zone {
|
||||
if !callback(&zones.Zone[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
43
vendor/github.com/exoscale/egoscale/zones_response.go
generated
vendored
Normal file
43
vendor/github.com/exoscale/egoscale/zones_response.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// code generated; DO NOT EDIT.
|
||||
|
||||
package egoscale
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Response returns the struct to unmarshal
|
||||
func (ListZones) Response() interface{} {
|
||||
return new(ListZonesResponse)
|
||||
}
|
||||
|
||||
// ListRequest returns itself
|
||||
func (ls *ListZones) ListRequest() (ListCommand, error) {
|
||||
if ls == nil {
|
||||
return nil, fmt.Errorf("%T cannot be nil", ls)
|
||||
}
|
||||
return ls, nil
|
||||
}
|
||||
|
||||
// SetPage sets the current apge
|
||||
func (ls *ListZones) SetPage(page int) {
|
||||
ls.Page = page
|
||||
}
|
||||
|
||||
// SetPageSize sets the page size
|
||||
func (ls *ListZones) SetPageSize(pageSize int) {
|
||||
ls.PageSize = pageSize
|
||||
}
|
||||
|
||||
// Each triggers the callback for each, valid answer or any non 404 issue
|
||||
func (ListZones) Each(resp interface{}, callback IterateItemFunc) {
|
||||
items, ok := resp.(*ListZonesResponse)
|
||||
if !ok {
|
||||
callback(nil, fmt.Errorf("wrong type, ListZonesResponse was expected, got %T", resp))
|
||||
return
|
||||
}
|
||||
|
||||
for i := range items.Zone {
|
||||
if !callback(&items.Zone[i], nil) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
82
vendor/github.com/oracle/oci-go-sdk/LICENSE.txt
generated
vendored
Normal file
82
vendor/github.com/oracle/oci-go-sdk/LICENSE.txt
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 or Apache License 2.0. See below for license terms. You may choose either license.
|
||||
____________________________
|
||||
The Universal Permissive License (UPL), Version 1.0
|
||||
Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
Subject to the condition set forth below, permission is hereby granted to any person obtaining a copy of this software, associated documentation and/or data (collectively the "Software"), free of charge and under any and all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or (ii) the Larger Works (as defined below), to deal in both
|
||||
|
||||
(a) the Software, and
|
||||
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software (each a "Larger Work" to which the Software is contributed by such licensors),
|
||||
|
||||
without restriction, including without limitation the rights to copy, create derivative works of, display, perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms.
|
||||
|
||||
This license is subject to the following condition:
|
||||
|
||||
The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
The Apache Software License, Version 2.0
|
||||
Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); You may not use this product except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. A copy of the license is also reproduced below. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
|
||||
http://www.apache.org/licenses/
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
1. Definitions.
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
339
vendor/github.com/oracle/oci-go-sdk/common/client.go
generated
vendored
Normal file
339
vendor/github.com/oracle/oci-go-sdk/common/client.go
generated
vendored
Normal file
|
@ -0,0 +1,339 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
// Package common provides supporting functions and structs used by service packages
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultHostURLTemplate The default url template for service hosts
|
||||
DefaultHostURLTemplate = "%s.%s.oraclecloud.com"
|
||||
|
||||
// requestHeaderAccept The key for passing a header to indicate Accept
|
||||
requestHeaderAccept = "Accept"
|
||||
|
||||
// requestHeaderAuthorization The key for passing a header to indicate Authorization
|
||||
requestHeaderAuthorization = "Authorization"
|
||||
|
||||
// requestHeaderContentLength The key for passing a header to indicate Content Length
|
||||
requestHeaderContentLength = "Content-Length"
|
||||
|
||||
// requestHeaderContentType The key for passing a header to indicate Content Type
|
||||
requestHeaderContentType = "Content-Type"
|
||||
|
||||
// requestHeaderDate The key for passing a header to indicate Date
|
||||
requestHeaderDate = "Date"
|
||||
|
||||
// requestHeaderIfMatch The key for passing a header to indicate If Match
|
||||
requestHeaderIfMatch = "if-match"
|
||||
|
||||
// requestHeaderOpcClientInfo The key for passing a header to indicate OPC Client Info
|
||||
requestHeaderOpcClientInfo = "opc-client-info"
|
||||
|
||||
// requestHeaderOpcRetryToken The key for passing a header to indicate OPC Retry Token
|
||||
requestHeaderOpcRetryToken = "opc-retry-token"
|
||||
|
||||
// requestHeaderOpcRequestID The key for unique Oracle-assigned identifier for the request.
|
||||
requestHeaderOpcRequestID = "opc-request-id"
|
||||
|
||||
// requestHeaderOpcClientRequestID The key for unique Oracle-assigned identifier for the request.
|
||||
requestHeaderOpcClientRequestID = "opc-client-request-id"
|
||||
|
||||
// requestHeaderUserAgent The key for passing a header to indicate User Agent
|
||||
requestHeaderUserAgent = "User-Agent"
|
||||
|
||||
// requestHeaderXContentSHA256 The key for passing a header to indicate SHA256 hash
|
||||
requestHeaderXContentSHA256 = "X-Content-SHA256"
|
||||
|
||||
// private constants
|
||||
defaultScheme = "https"
|
||||
defaultSDKMarker = "Oracle-GoSDK"
|
||||
defaultUserAgentTemplate = "%s/%s (%s/%s; go/%s)" //SDK/SDKVersion (OS/OSVersion; Lang/LangVersion)
|
||||
defaultTimeout = 60 * time.Second
|
||||
defaultConfigFileName = "config"
|
||||
defaultConfigDirName = ".oci"
|
||||
secondaryConfigDirName = ".oraclebmc"
|
||||
maxBodyLenForDebug = 1024 * 1000
|
||||
)
|
||||
|
||||
// RequestInterceptor function used to customize the request before calling the underlying service
|
||||
type RequestInterceptor func(*http.Request) error
|
||||
|
||||
// HTTPRequestDispatcher wraps the execution of a http request, it is generally implemented by
|
||||
// http.Client.Do, but can be customized for testing
|
||||
type HTTPRequestDispatcher interface {
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// BaseClient struct implements all basic operations to call oci web services.
|
||||
type BaseClient struct {
|
||||
//HTTPClient performs the http network operations
|
||||
HTTPClient HTTPRequestDispatcher
|
||||
|
||||
//Signer performs auth operation
|
||||
Signer HTTPRequestSigner
|
||||
|
||||
//A request interceptor can be used to customize the request before signing and dispatching
|
||||
Interceptor RequestInterceptor
|
||||
|
||||
//The host of the service
|
||||
Host string
|
||||
|
||||
//The user agent
|
||||
UserAgent string
|
||||
|
||||
//Base path for all operations of this client
|
||||
BasePath string
|
||||
}
|
||||
|
||||
func defaultUserAgent() string {
|
||||
userAgent := fmt.Sprintf(defaultUserAgentTemplate, defaultSDKMarker, Version(), runtime.GOOS, runtime.GOARCH, runtime.Version())
|
||||
return userAgent
|
||||
}
|
||||
|
||||
var clientCounter int64
|
||||
|
||||
func getNextSeed() int64 {
|
||||
newCounterValue := atomic.AddInt64(&clientCounter, 1)
|
||||
return newCounterValue + time.Now().UnixNano()
|
||||
}
|
||||
|
||||
func newBaseClient(signer HTTPRequestSigner, dispatcher HTTPRequestDispatcher) BaseClient {
|
||||
rand.Seed(getNextSeed())
|
||||
return BaseClient{
|
||||
UserAgent: defaultUserAgent(),
|
||||
Interceptor: nil,
|
||||
Signer: signer,
|
||||
HTTPClient: dispatcher,
|
||||
}
|
||||
}
|
||||
|
||||
func defaultHTTPDispatcher() http.Client {
|
||||
httpClient := http.Client{
|
||||
Timeout: defaultTimeout,
|
||||
}
|
||||
return httpClient
|
||||
}
|
||||
|
||||
func defaultBaseClient(provider KeyProvider) BaseClient {
|
||||
dispatcher := defaultHTTPDispatcher()
|
||||
signer := DefaultRequestSigner(provider)
|
||||
return newBaseClient(signer, &dispatcher)
|
||||
}
|
||||
|
||||
//DefaultBaseClientWithSigner creates a default base client with a given signer
|
||||
func DefaultBaseClientWithSigner(signer HTTPRequestSigner) BaseClient {
|
||||
dispatcher := defaultHTTPDispatcher()
|
||||
return newBaseClient(signer, &dispatcher)
|
||||
}
|
||||
|
||||
// NewClientWithConfig Create a new client with a configuration provider, the configuration provider
|
||||
// will be used for the default signer as well as reading the region
|
||||
// This function does not check for valid regions to implement forward compatibility
|
||||
func NewClientWithConfig(configProvider ConfigurationProvider) (client BaseClient, err error) {
|
||||
var ok bool
|
||||
if ok, err = IsConfigurationProviderValid(configProvider); !ok {
|
||||
err = fmt.Errorf("can not create client, bad configuration: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
client = defaultBaseClient(configProvider)
|
||||
return
|
||||
}
|
||||
|
||||
func getHomeFolder() string {
|
||||
current, e := user.Current()
|
||||
if e != nil {
|
||||
//Give up and try to return something sensible
|
||||
home := os.Getenv("HOME")
|
||||
if home == "" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
return home
|
||||
}
|
||||
return current.HomeDir
|
||||
}
|
||||
|
||||
// DefaultConfigProvider returns the default config provider. The default config provider
|
||||
// will look for configurations in 3 places: file in $HOME/.oci/config, HOME/.obmcs/config and
|
||||
// variables names starting with the string TF_VAR. If the same configuration is found in multiple
|
||||
// places the provider will prefer the first one.
|
||||
func DefaultConfigProvider() ConfigurationProvider {
|
||||
homeFolder := getHomeFolder()
|
||||
defaultConfigFile := path.Join(homeFolder, defaultConfigDirName, defaultConfigFileName)
|
||||
secondaryConfigFile := path.Join(homeFolder, secondaryConfigDirName, defaultConfigFileName)
|
||||
|
||||
defaultFileProvider, _ := ConfigurationProviderFromFile(defaultConfigFile, "")
|
||||
secondaryFileProvider, _ := ConfigurationProviderFromFile(secondaryConfigFile, "")
|
||||
environmentProvider := environmentConfigurationProvider{EnvironmentVariablePrefix: "TF_VAR"}
|
||||
|
||||
provider, _ := ComposingConfigurationProvider([]ConfigurationProvider{defaultFileProvider, secondaryFileProvider, environmentProvider})
|
||||
Debugf("Configuration provided by: %s", provider)
|
||||
return provider
|
||||
}
|
||||
|
||||
func (client *BaseClient) prepareRequest(request *http.Request) (err error) {
|
||||
if client.UserAgent == "" {
|
||||
return fmt.Errorf("user agent can not be blank")
|
||||
}
|
||||
|
||||
if request.Header == nil {
|
||||
request.Header = http.Header{}
|
||||
}
|
||||
request.Header.Set(requestHeaderUserAgent, client.UserAgent)
|
||||
request.Header.Set(requestHeaderDate, time.Now().UTC().Format(http.TimeFormat))
|
||||
|
||||
if !strings.Contains(client.Host, "http") &&
|
||||
!strings.Contains(client.Host, "https") {
|
||||
client.Host = fmt.Sprintf("%s://%s", defaultScheme, client.Host)
|
||||
}
|
||||
|
||||
clientURL, err := url.Parse(client.Host)
|
||||
if err != nil {
|
||||
return fmt.Errorf("host is invalid. %s", err.Error())
|
||||
}
|
||||
request.URL.Host = clientURL.Host
|
||||
request.URL.Scheme = clientURL.Scheme
|
||||
currentPath := request.URL.Path
|
||||
if !strings.Contains(currentPath, fmt.Sprintf("/%s", client.BasePath)) {
|
||||
request.URL.Path = path.Clean(fmt.Sprintf("/%s/%s", client.BasePath, currentPath))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (client BaseClient) intercept(request *http.Request) (err error) {
|
||||
if client.Interceptor != nil {
|
||||
err = client.Interceptor(request)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func checkForSuccessfulResponse(res *http.Response) error {
|
||||
familyStatusCode := res.StatusCode / 100
|
||||
if familyStatusCode == 4 || familyStatusCode == 5 {
|
||||
return newServiceFailureFromResponse(res)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// OCIRequest is any request made to an OCI service.
|
||||
type OCIRequest interface {
|
||||
// HTTPRequest assembles an HTTP request.
|
||||
HTTPRequest(method, path string) (http.Request, error)
|
||||
}
|
||||
|
||||
// RequestMetadata is metadata about an OCIRequest. This structure represents the behavior exhibited by the SDK when
|
||||
// issuing (or reissuing) a request.
|
||||
type RequestMetadata struct {
|
||||
// RetryPolicy is the policy for reissuing the request. If no retry policy is set on the request,
|
||||
// then the request will be issued exactly once.
|
||||
RetryPolicy *RetryPolicy
|
||||
}
|
||||
|
||||
// OCIResponse is the response from issuing a request to an OCI service.
|
||||
type OCIResponse interface {
|
||||
// HTTPResponse returns the raw HTTP response.
|
||||
HTTPResponse() *http.Response
|
||||
}
|
||||
|
||||
// OCIOperation is the generalization of a request-response cycle undergone by an OCI service.
|
||||
type OCIOperation func(context.Context, OCIRequest) (OCIResponse, error)
|
||||
|
||||
//ClientCallDetails a set of settings used by the a single Call operation of the http Client
|
||||
type ClientCallDetails struct {
|
||||
Signer HTTPRequestSigner
|
||||
}
|
||||
|
||||
// Call executes the http request with the given context
|
||||
func (client BaseClient) Call(ctx context.Context, request *http.Request) (response *http.Response, err error) {
|
||||
return client.CallWithDetails(ctx, request, ClientCallDetails{Signer: client.Signer})
|
||||
}
|
||||
|
||||
// CallWithDetails executes the http request, the given context using details specified in the paremeters, this function
|
||||
// provides a way to override some settings present in the client
|
||||
func (client BaseClient) CallWithDetails(ctx context.Context, request *http.Request, details ClientCallDetails) (response *http.Response, err error) {
|
||||
Debugln("Atempting to call downstream service")
|
||||
request = request.WithContext(ctx)
|
||||
|
||||
err = client.prepareRequest(request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//Intercept
|
||||
err = client.intercept(request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//Sign the request
|
||||
err = details.Signer.Sign(request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
IfDebug(func() {
|
||||
dumpBody := true
|
||||
if request.ContentLength > maxBodyLenForDebug {
|
||||
Debugf("not dumping body too big\n")
|
||||
dumpBody = false
|
||||
}
|
||||
dumpBody = dumpBody && defaultLogger.LogLevel() == verboseLogging
|
||||
if dump, e := httputil.DumpRequestOut(request, dumpBody); e == nil {
|
||||
Debugf("Dump Request %s", string(dump))
|
||||
} else {
|
||||
Debugf("%v\n", e)
|
||||
}
|
||||
})
|
||||
|
||||
//Execute the http request
|
||||
response, err = client.HTTPClient.Do(request)
|
||||
|
||||
IfDebug(func() {
|
||||
if err != nil {
|
||||
Debugf("%v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
dumpBody := true
|
||||
if response.ContentLength > maxBodyLenForDebug {
|
||||
Debugf("not dumping body too big\n")
|
||||
dumpBody = false
|
||||
}
|
||||
|
||||
dumpBody = dumpBody && defaultLogger.LogLevel() == verboseLogging
|
||||
if dump, e := httputil.DumpResponse(response, dumpBody); e == nil {
|
||||
Debugf("Dump Response %s", string(dump))
|
||||
} else {
|
||||
Debugf("%v\n", e)
|
||||
}
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = checkForSuccessfulResponse(response)
|
||||
return
|
||||
}
|
||||
|
||||
//CloseBodyIfValid closes the body of an http response if the response and the body are valid
|
||||
func CloseBodyIfValid(httpResponse *http.Response) {
|
||||
if httpResponse != nil && httpResponse.Body != nil {
|
||||
httpResponse.Body.Close()
|
||||
}
|
||||
}
|
137
vendor/github.com/oracle/oci-go-sdk/common/common.go
generated
vendored
Normal file
137
vendor/github.com/oracle/oci-go-sdk/common/common.go
generated
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//Region type for regions
|
||||
type Region string
|
||||
|
||||
const (
|
||||
//RegionSEA region SEA
|
||||
RegionSEA Region = "sea"
|
||||
//RegionCAToronto1 region for toronto
|
||||
RegionCAToronto1 Region = "ca-toronto-1"
|
||||
//RegionPHX region PHX
|
||||
RegionPHX Region = "us-phoenix-1"
|
||||
//RegionIAD region IAD
|
||||
RegionIAD Region = "us-ashburn-1"
|
||||
//RegionFRA region FRA
|
||||
RegionFRA Region = "eu-frankfurt-1"
|
||||
//RegionLHR region LHR
|
||||
RegionLHR Region = "uk-london-1"
|
||||
|
||||
//RegionUSLangley1 region for langley
|
||||
RegionUSLangley1 Region = "us-langley-1"
|
||||
//RegionUSLuke1 region for luke
|
||||
RegionUSLuke1 Region = "us-luke-1"
|
||||
|
||||
//RegionUSGovAshburn1 region for langley
|
||||
RegionUSGovAshburn1 Region = "us-gov-ashburn-1"
|
||||
//RegionUSGovChicago1 region for luke
|
||||
RegionUSGovChicago1 Region = "us-gov-chicago-1"
|
||||
//RegionUSGovPhoenix1 region for luke
|
||||
RegionUSGovPhoenix1 Region = "us-gov-phoenix-1"
|
||||
)
|
||||
|
||||
var realm = map[string]string{
|
||||
"oc1": "oraclecloud.com",
|
||||
"oc2": "oraclegovcloud.com",
|
||||
"oc3": "oraclegovcloud.com",
|
||||
}
|
||||
|
||||
var regionRealm = map[Region]string{
|
||||
RegionPHX: "oc1",
|
||||
RegionIAD: "oc1",
|
||||
RegionFRA: "oc1",
|
||||
RegionLHR: "oc1",
|
||||
RegionCAToronto1: "oc1",
|
||||
|
||||
RegionUSLangley1: "oc2",
|
||||
RegionUSLuke1: "oc2",
|
||||
|
||||
RegionUSGovAshburn1: "oc3",
|
||||
RegionUSGovChicago1: "oc3",
|
||||
RegionUSGovPhoenix1: "oc3",
|
||||
}
|
||||
|
||||
// Endpoint returns a endpoint for a service
|
||||
func (region Region) Endpoint(service string) string {
|
||||
return fmt.Sprintf("%s.%s.%s", service, region, region.secondLevelDomain())
|
||||
}
|
||||
|
||||
// EndpointForTemplate returns a endpoint for a service based on template
|
||||
func (region Region) EndpointForTemplate(service string, serviceEndpointTemplate string) string {
|
||||
if serviceEndpointTemplate == "" {
|
||||
return region.Endpoint(service)
|
||||
}
|
||||
|
||||
// replace service prefix
|
||||
endpoint := strings.Replace(serviceEndpointTemplate, "{serviceEndpointPrefix}", service, 1)
|
||||
|
||||
// replace region
|
||||
endpoint = strings.Replace(endpoint, "{region}", string(region), 1)
|
||||
|
||||
// replace second level domain
|
||||
endpoint = strings.Replace(endpoint, "{secondLevelDomain}", region.secondLevelDomain(), 1)
|
||||
|
||||
return endpoint
|
||||
}
|
||||
|
||||
func (region Region) secondLevelDomain() string {
|
||||
if realmID, ok := regionRealm[region]; ok {
|
||||
if secondLevelDomain, ok := realm[realmID]; ok {
|
||||
return secondLevelDomain
|
||||
}
|
||||
}
|
||||
|
||||
Debugf("cannot find realm for region : %s, return default realm value.", region)
|
||||
return realm["oc1"]
|
||||
}
|
||||
|
||||
//StringToRegion convert a string to Region type
|
||||
func StringToRegion(stringRegion string) (r Region) {
|
||||
switch strings.ToLower(stringRegion) {
|
||||
case "sea":
|
||||
r = RegionSEA
|
||||
case "ca-toronto-1":
|
||||
r = RegionCAToronto1
|
||||
case "phx", "us-phoenix-1":
|
||||
r = RegionPHX
|
||||
case "iad", "us-ashburn-1":
|
||||
r = RegionIAD
|
||||
case "fra", "eu-frankfurt-1":
|
||||
r = RegionFRA
|
||||
case "lhr", "uk-london-1":
|
||||
r = RegionLHR
|
||||
case "us-langley-1":
|
||||
r = RegionUSLangley1
|
||||
case "us-luke-1":
|
||||
r = RegionUSLuke1
|
||||
case "us-gov-ashburn-1":
|
||||
r = RegionUSGovAshburn1
|
||||
case "us-gov-chicago-1":
|
||||
r = RegionUSGovChicago1
|
||||
case "us-gov-phoenix-1":
|
||||
r = RegionUSGovPhoenix1
|
||||
default:
|
||||
r = Region(stringRegion)
|
||||
Debugf("region named: %s, is not recognized", stringRegion)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// canStringBeRegion test if the string can be a region, if it can, returns the string as is, otherwise it
|
||||
// returns an error
|
||||
var blankRegex = regexp.MustCompile("\\s")
|
||||
|
||||
func canStringBeRegion(stringRegion string) (region string, err error) {
|
||||
if blankRegex.MatchString(stringRegion) || stringRegion == "" {
|
||||
return "", fmt.Errorf("region can not be empty or have spaces")
|
||||
}
|
||||
return stringRegion, nil
|
||||
}
|
535
vendor/github.com/oracle/oci-go-sdk/common/configuration.go
generated
vendored
Normal file
535
vendor/github.com/oracle/oci-go-sdk/common/configuration.go
generated
vendored
Normal file
|
@ -0,0 +1,535 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ConfigurationProvider wraps information about the account owner
|
||||
type ConfigurationProvider interface {
|
||||
KeyProvider
|
||||
TenancyOCID() (string, error)
|
||||
UserOCID() (string, error)
|
||||
KeyFingerprint() (string, error)
|
||||
Region() (string, error)
|
||||
}
|
||||
|
||||
// IsConfigurationProviderValid Tests all parts of the configuration provider do not return an error
|
||||
func IsConfigurationProviderValid(conf ConfigurationProvider) (ok bool, err error) {
|
||||
baseFn := []func() (string, error){conf.TenancyOCID, conf.UserOCID, conf.KeyFingerprint, conf.Region, conf.KeyID}
|
||||
for _, fn := range baseFn {
|
||||
_, err = fn()
|
||||
ok = err == nil
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
_, err = conf.PrivateRSAKey()
|
||||
ok = err == nil
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// rawConfigurationProvider allows a user to simply construct a configuration provider from raw values.
|
||||
type rawConfigurationProvider struct {
|
||||
tenancy string
|
||||
user string
|
||||
region string
|
||||
fingerprint string
|
||||
privateKey string
|
||||
privateKeyPassphrase *string
|
||||
}
|
||||
|
||||
// NewRawConfigurationProvider will create a rawConfigurationProvider
|
||||
func NewRawConfigurationProvider(tenancy, user, region, fingerprint, privateKey string, privateKeyPassphrase *string) ConfigurationProvider {
|
||||
return rawConfigurationProvider{tenancy, user, region, fingerprint, privateKey, privateKeyPassphrase}
|
||||
}
|
||||
|
||||
func (p rawConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) {
|
||||
return PrivateKeyFromBytes([]byte(p.privateKey), p.privateKeyPassphrase)
|
||||
}
|
||||
|
||||
func (p rawConfigurationProvider) KeyID() (keyID string, err error) {
|
||||
tenancy, err := p.TenancyOCID()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := p.UserOCID()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fingerprint, err := p.KeyFingerprint()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s/%s", tenancy, user, fingerprint), nil
|
||||
}
|
||||
|
||||
func (p rawConfigurationProvider) TenancyOCID() (string, error) {
|
||||
if p.tenancy == "" {
|
||||
return "", fmt.Errorf("tenancy OCID can not be empty")
|
||||
}
|
||||
return p.tenancy, nil
|
||||
}
|
||||
|
||||
func (p rawConfigurationProvider) UserOCID() (string, error) {
|
||||
if p.user == "" {
|
||||
return "", fmt.Errorf("user OCID can not be empty")
|
||||
}
|
||||
return p.user, nil
|
||||
}
|
||||
|
||||
func (p rawConfigurationProvider) KeyFingerprint() (string, error) {
|
||||
if p.fingerprint == "" {
|
||||
return "", fmt.Errorf("fingerprint can not be empty")
|
||||
}
|
||||
return p.fingerprint, nil
|
||||
}
|
||||
|
||||
func (p rawConfigurationProvider) Region() (string, error) {
|
||||
return canStringBeRegion(p.region)
|
||||
}
|
||||
|
||||
// environmentConfigurationProvider reads configuration from environment variables
|
||||
type environmentConfigurationProvider struct {
|
||||
PrivateKeyPassword string
|
||||
EnvironmentVariablePrefix string
|
||||
}
|
||||
|
||||
// ConfigurationProviderEnvironmentVariables creates a ConfigurationProvider from a uniform set of environment variables starting with a prefix
|
||||
// The env variables should look like: [prefix]_private_key_path, [prefix]_tenancy_ocid, [prefix]_user_ocid, [prefix]_fingerprint
|
||||
// [prefix]_region
|
||||
func ConfigurationProviderEnvironmentVariables(environmentVariablePrefix, privateKeyPassword string) ConfigurationProvider {
|
||||
return environmentConfigurationProvider{EnvironmentVariablePrefix: environmentVariablePrefix,
|
||||
PrivateKeyPassword: privateKeyPassword}
|
||||
}
|
||||
|
||||
func (p environmentConfigurationProvider) String() string {
|
||||
return fmt.Sprintf("Configuration provided by environment variables prefixed with: %s", p.EnvironmentVariablePrefix)
|
||||
}
|
||||
|
||||
func (p environmentConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) {
|
||||
environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "private_key_path")
|
||||
var ok bool
|
||||
var value string
|
||||
if value, ok = os.LookupEnv(environmentVariable); !ok {
|
||||
return nil, fmt.Errorf("can not read PrivateKey from env variable: %s", environmentVariable)
|
||||
}
|
||||
|
||||
expandedPath := expandPath(value)
|
||||
pemFileContent, err := ioutil.ReadFile(expandedPath)
|
||||
if err != nil {
|
||||
Debugln("Can not read PrivateKey location from environment variable: " + environmentVariable)
|
||||
return
|
||||
}
|
||||
|
||||
key, err = PrivateKeyFromBytes(pemFileContent, &p.PrivateKeyPassword)
|
||||
return
|
||||
}
|
||||
|
||||
func (p environmentConfigurationProvider) KeyID() (keyID string, err error) {
|
||||
ocid, err := p.TenancyOCID()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
userocid, err := p.UserOCID()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fingerprint, err := p.KeyFingerprint()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s/%s", ocid, userocid, fingerprint), nil
|
||||
}
|
||||
|
||||
func (p environmentConfigurationProvider) TenancyOCID() (value string, err error) {
|
||||
environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "tenancy_ocid")
|
||||
var ok bool
|
||||
if value, ok = os.LookupEnv(environmentVariable); !ok {
|
||||
err = fmt.Errorf("can not read Tenancy from environment variable %s", environmentVariable)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (p environmentConfigurationProvider) UserOCID() (value string, err error) {
|
||||
environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "user_ocid")
|
||||
var ok bool
|
||||
if value, ok = os.LookupEnv(environmentVariable); !ok {
|
||||
err = fmt.Errorf("can not read user id from environment variable %s", environmentVariable)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (p environmentConfigurationProvider) KeyFingerprint() (value string, err error) {
|
||||
environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "fingerprint")
|
||||
var ok bool
|
||||
if value, ok = os.LookupEnv(environmentVariable); !ok {
|
||||
err = fmt.Errorf("can not read fingerprint from environment variable %s", environmentVariable)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (p environmentConfigurationProvider) Region() (value string, err error) {
|
||||
environmentVariable := fmt.Sprintf("%s_%s", p.EnvironmentVariablePrefix, "region")
|
||||
var ok bool
|
||||
if value, ok = os.LookupEnv(environmentVariable); !ok {
|
||||
err = fmt.Errorf("can not read region from environment variable %s", environmentVariable)
|
||||
return value, err
|
||||
}
|
||||
|
||||
return canStringBeRegion(value)
|
||||
}
|
||||
|
||||
// fileConfigurationProvider. reads configuration information from a file
|
||||
type fileConfigurationProvider struct {
|
||||
//The path to the configuration file
|
||||
ConfigPath string
|
||||
|
||||
//The password for the private key
|
||||
PrivateKeyPassword string
|
||||
|
||||
//The profile for the configuration
|
||||
Profile string
|
||||
|
||||
//ConfigFileInfo
|
||||
FileInfo *configFileInfo
|
||||
}
|
||||
|
||||
// ConfigurationProviderFromFile creates a configuration provider from a configuration file
|
||||
// by reading the "DEFAULT" profile
|
||||
func ConfigurationProviderFromFile(configFilePath, privateKeyPassword string) (ConfigurationProvider, error) {
|
||||
if configFilePath == "" {
|
||||
return nil, fmt.Errorf("config file path can not be empty")
|
||||
}
|
||||
|
||||
return fileConfigurationProvider{
|
||||
ConfigPath: configFilePath,
|
||||
PrivateKeyPassword: privateKeyPassword,
|
||||
Profile: "DEFAULT"}, nil
|
||||
}
|
||||
|
||||
// ConfigurationProviderFromFileWithProfile creates a configuration provider from a configuration file
|
||||
// and the given profile
|
||||
func ConfigurationProviderFromFileWithProfile(configFilePath, profile, privateKeyPassword string) (ConfigurationProvider, error) {
|
||||
if configFilePath == "" {
|
||||
return nil, fmt.Errorf("config file path can not be empty")
|
||||
}
|
||||
|
||||
return fileConfigurationProvider{
|
||||
ConfigPath: configFilePath,
|
||||
PrivateKeyPassword: privateKeyPassword,
|
||||
Profile: profile}, nil
|
||||
}
|
||||
|
||||
type configFileInfo struct {
|
||||
UserOcid, Fingerprint, KeyFilePath, TenancyOcid, Region, Passphrase string
|
||||
PresentConfiguration byte
|
||||
}
|
||||
|
||||
const (
|
||||
hasTenancy = 1 << iota
|
||||
hasUser
|
||||
hasFingerprint
|
||||
hasRegion
|
||||
hasKeyFile
|
||||
hasPassphrase
|
||||
none
|
||||
)
|
||||
|
||||
var profileRegex = regexp.MustCompile(`^\[(.*)\]`)
|
||||
|
||||
func parseConfigFile(data []byte, profile string) (info *configFileInfo, err error) {
|
||||
|
||||
if len(data) == 0 {
|
||||
return nil, fmt.Errorf("configuration file content is empty")
|
||||
}
|
||||
|
||||
content := string(data)
|
||||
splitContent := strings.Split(content, "\n")
|
||||
|
||||
//Look for profile
|
||||
for i, line := range splitContent {
|
||||
if match := profileRegex.FindStringSubmatch(line); match != nil && len(match) > 1 && match[1] == profile {
|
||||
start := i + 1
|
||||
return parseConfigAtLine(start, splitContent)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("configuration file did not contain profile: %s", profile)
|
||||
}
|
||||
|
||||
func parseConfigAtLine(start int, content []string) (info *configFileInfo, err error) {
|
||||
var configurationPresent byte
|
||||
info = &configFileInfo{}
|
||||
for i := start; i < len(content); i++ {
|
||||
line := content[i]
|
||||
if profileRegex.MatchString(line) {
|
||||
break
|
||||
}
|
||||
|
||||
if !strings.Contains(line, "=") {
|
||||
continue
|
||||
}
|
||||
|
||||
splits := strings.Split(line, "=")
|
||||
switch key, value := strings.TrimSpace(splits[0]), strings.TrimSpace(splits[1]); strings.ToLower(key) {
|
||||
case "passphrase", "pass_phrase":
|
||||
configurationPresent = configurationPresent | hasPassphrase
|
||||
info.Passphrase = value
|
||||
case "user":
|
||||
configurationPresent = configurationPresent | hasUser
|
||||
info.UserOcid = value
|
||||
case "fingerprint":
|
||||
configurationPresent = configurationPresent | hasFingerprint
|
||||
info.Fingerprint = value
|
||||
case "key_file":
|
||||
configurationPresent = configurationPresent | hasKeyFile
|
||||
info.KeyFilePath = value
|
||||
case "tenancy":
|
||||
configurationPresent = configurationPresent | hasTenancy
|
||||
info.TenancyOcid = value
|
||||
case "region":
|
||||
configurationPresent = configurationPresent | hasRegion
|
||||
info.Region = value
|
||||
}
|
||||
}
|
||||
info.PresentConfiguration = configurationPresent
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
// cleans and expands the path if it contains a tilde , returns the expanded path or the input path as is if not expansion
|
||||
// was performed
|
||||
func expandPath(filepath string) (expandedPath string) {
|
||||
cleanedPath := path.Clean(filepath)
|
||||
expandedPath = cleanedPath
|
||||
if strings.HasPrefix(cleanedPath, "~") {
|
||||
rest := cleanedPath[2:]
|
||||
expandedPath = path.Join(getHomeFolder(), rest)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func openConfigFile(configFilePath string) (data []byte, err error) {
|
||||
expandedPath := expandPath(configFilePath)
|
||||
data, err = ioutil.ReadFile(expandedPath)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("can not read config file: %s due to: %s", configFilePath, err.Error())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (p fileConfigurationProvider) String() string {
|
||||
return fmt.Sprintf("Configuration provided by file: %s", p.ConfigPath)
|
||||
}
|
||||
|
||||
func (p fileConfigurationProvider) readAndParseConfigFile() (info *configFileInfo, err error) {
|
||||
if p.FileInfo != nil {
|
||||
return p.FileInfo, nil
|
||||
}
|
||||
|
||||
if p.ConfigPath == "" {
|
||||
return nil, fmt.Errorf("configuration path can not be empty")
|
||||
}
|
||||
|
||||
data, err := openConfigFile(p.ConfigPath)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error while parsing config file: %s. Due to: %s", p.ConfigPath, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
p.FileInfo, err = parseConfigFile(data, p.Profile)
|
||||
return p.FileInfo, err
|
||||
}
|
||||
|
||||
func presentOrError(value string, expectedConf, presentConf byte, confMissing string) (string, error) {
|
||||
if presentConf&expectedConf == expectedConf {
|
||||
return value, nil
|
||||
}
|
||||
return "", errors.New(confMissing + " configuration is missing from file")
|
||||
}
|
||||
|
||||
func (p fileConfigurationProvider) TenancyOCID() (value string, err error) {
|
||||
info, err := p.readAndParseConfigFile()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
value, err = presentOrError(info.TenancyOcid, hasTenancy, info.PresentConfiguration, "tenancy")
|
||||
return
|
||||
}
|
||||
|
||||
func (p fileConfigurationProvider) UserOCID() (value string, err error) {
|
||||
info, err := p.readAndParseConfigFile()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
value, err = presentOrError(info.UserOcid, hasUser, info.PresentConfiguration, "user")
|
||||
return
|
||||
}
|
||||
|
||||
func (p fileConfigurationProvider) KeyFingerprint() (value string, err error) {
|
||||
info, err := p.readAndParseConfigFile()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
||||
return
|
||||
}
|
||||
value, err = presentOrError(info.Fingerprint, hasFingerprint, info.PresentConfiguration, "fingerprint")
|
||||
return
|
||||
}
|
||||
|
||||
func (p fileConfigurationProvider) KeyID() (keyID string, err error) {
|
||||
info, err := p.readAndParseConfigFile()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s/%s", info.TenancyOcid, info.UserOcid, info.Fingerprint), nil
|
||||
}
|
||||
|
||||
func (p fileConfigurationProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) {
|
||||
info, err := p.readAndParseConfigFile()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("can not read tenancy configuration due to: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
filePath, err := presentOrError(info.KeyFilePath, hasKeyFile, info.PresentConfiguration, "key file path")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
expandedPath := expandPath(filePath)
|
||||
pemFileContent, err := ioutil.ReadFile(expandedPath)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("can not read PrivateKey from configuration file due to: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
password := p.PrivateKeyPassword
|
||||
|
||||
if password == "" && ((info.PresentConfiguration & hasPassphrase) == hasPassphrase) {
|
||||
password = info.Passphrase
|
||||
}
|
||||
|
||||
key, err = PrivateKeyFromBytes(pemFileContent, &password)
|
||||
return
|
||||
}
|
||||
|
||||
func (p fileConfigurationProvider) Region() (value string, err error) {
|
||||
info, err := p.readAndParseConfigFile()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("can not read region configuration due to: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
value, err = presentOrError(info.Region, hasRegion, info.PresentConfiguration, "region")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return canStringBeRegion(value)
|
||||
}
|
||||
|
||||
// A configuration provider that look for information in multiple configuration providers
|
||||
type composingConfigurationProvider struct {
|
||||
Providers []ConfigurationProvider
|
||||
}
|
||||
|
||||
// ComposingConfigurationProvider creates a composing configuration provider with the given slice of configuration providers
|
||||
// A composing provider will return the configuration of the first provider that has the required property
|
||||
// if no provider has the property it will return an error.
|
||||
func ComposingConfigurationProvider(providers []ConfigurationProvider) (ConfigurationProvider, error) {
|
||||
if len(providers) == 0 {
|
||||
return nil, fmt.Errorf("providers can not be an empty slice")
|
||||
}
|
||||
|
||||
for i, p := range providers {
|
||||
if p == nil {
|
||||
return nil, fmt.Errorf("provider in position: %d is nil. ComposingConfiurationProvider does not support nil values", i)
|
||||
}
|
||||
}
|
||||
return composingConfigurationProvider{Providers: providers}, nil
|
||||
}
|
||||
|
||||
func (c composingConfigurationProvider) TenancyOCID() (string, error) {
|
||||
for _, p := range c.Providers {
|
||||
val, err := p.TenancyOCID()
|
||||
if err == nil {
|
||||
return val, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("did not find a proper configuration for tenancy")
|
||||
}
|
||||
|
||||
func (c composingConfigurationProvider) UserOCID() (string, error) {
|
||||
for _, p := range c.Providers {
|
||||
val, err := p.UserOCID()
|
||||
if err == nil {
|
||||
return val, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("did not find a proper configuration for user")
|
||||
}
|
||||
|
||||
func (c composingConfigurationProvider) KeyFingerprint() (string, error) {
|
||||
for _, p := range c.Providers {
|
||||
val, err := p.KeyFingerprint()
|
||||
if err == nil {
|
||||
return val, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("did not find a proper configuration for keyFingerprint")
|
||||
}
|
||||
func (c composingConfigurationProvider) Region() (string, error) {
|
||||
for _, p := range c.Providers {
|
||||
val, err := p.Region()
|
||||
if err == nil {
|
||||
return val, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("did not find a proper configuration for region")
|
||||
}
|
||||
|
||||
func (c composingConfigurationProvider) KeyID() (string, error) {
|
||||
for _, p := range c.Providers {
|
||||
val, err := p.KeyID()
|
||||
if err == nil {
|
||||
return val, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("did not find a proper configuration for key id")
|
||||
}
|
||||
|
||||
func (c composingConfigurationProvider) PrivateRSAKey() (*rsa.PrivateKey, error) {
|
||||
for _, p := range c.Providers {
|
||||
val, err := p.PrivateRSAKey()
|
||||
if err == nil {
|
||||
return val, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("did not find a proper configuration for private key")
|
||||
}
|
98
vendor/github.com/oracle/oci-go-sdk/common/errors.go
generated
vendored
Normal file
98
vendor/github.com/oracle/oci-go-sdk/common/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ServiceError models all potential errors generated the service call
|
||||
type ServiceError interface {
|
||||
// The http status code of the error
|
||||
GetHTTPStatusCode() int
|
||||
|
||||
// The human-readable error string as sent by the service
|
||||
GetMessage() string
|
||||
|
||||
// A short error code that defines the error, meant for programmatic parsing.
|
||||
// See https://docs.us-phoenix-1.oraclecloud.com/Content/API/References/apierrors.htm
|
||||
GetCode() string
|
||||
|
||||
// Unique Oracle-assigned identifier for the request.
|
||||
// If you need to contact Oracle about a particular request, please provide the request ID.
|
||||
GetOpcRequestID() string
|
||||
}
|
||||
|
||||
type servicefailure struct {
|
||||
StatusCode int
|
||||
Code string `json:"code,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
OpcRequestID string `json:"opc-request-id"`
|
||||
}
|
||||
|
||||
func newServiceFailureFromResponse(response *http.Response) error {
|
||||
var err error
|
||||
|
||||
se := servicefailure{
|
||||
StatusCode: response.StatusCode,
|
||||
Code: "BadErrorResponse",
|
||||
OpcRequestID: response.Header.Get("opc-request-id")}
|
||||
|
||||
//If there is an error consume the body, entirely
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
se.Message = fmt.Sprintf("The body of the response was not readable, due to :%s", err.Error())
|
||||
return se
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &se)
|
||||
if err != nil {
|
||||
Debugf("Error response could not be parsed due to: %s", err.Error())
|
||||
se.Message = fmt.Sprintf("Failed to parse json from response body due to: %s. With response body %s.", err.Error(), string(body[:]))
|
||||
return se
|
||||
}
|
||||
return se
|
||||
}
|
||||
|
||||
func (se servicefailure) Error() string {
|
||||
return fmt.Sprintf("Service error:%s. %s. http status code: %d. Opc request id: %s",
|
||||
se.Code, se.Message, se.StatusCode, se.OpcRequestID)
|
||||
}
|
||||
|
||||
func (se servicefailure) GetHTTPStatusCode() int {
|
||||
return se.StatusCode
|
||||
|
||||
}
|
||||
|
||||
func (se servicefailure) GetMessage() string {
|
||||
return se.Message
|
||||
}
|
||||
|
||||
func (se servicefailure) GetCode() string {
|
||||
return se.Code
|
||||
}
|
||||
|
||||
func (se servicefailure) GetOpcRequestID() string {
|
||||
return se.OpcRequestID
|
||||
}
|
||||
|
||||
// IsServiceError returns false if the error is not service side, otherwise true
|
||||
// additionally it returns an interface representing the ServiceError
|
||||
func IsServiceError(err error) (failure ServiceError, ok bool) {
|
||||
failure, ok = err.(servicefailure)
|
||||
return
|
||||
}
|
||||
|
||||
type deadlineExceededByBackoffError struct{}
|
||||
|
||||
func (deadlineExceededByBackoffError) Error() string {
|
||||
return "now() + computed backoff duration exceeds request deadline"
|
||||
}
|
||||
|
||||
// DeadlineExceededByBackoff is the error returned by Call() when GetNextDuration() returns a time.Duration that would
|
||||
// force the user to wait past the request deadline before re-issuing a request. This enables us to exit early, since
|
||||
// we cannot succeed based on the configured retry policy.
|
||||
var DeadlineExceededByBackoff error = deadlineExceededByBackoffError{}
|
245
vendor/github.com/oracle/oci-go-sdk/common/helpers.go
generated
vendored
Normal file
245
vendor/github.com/oracle/oci-go-sdk/common/helpers.go
generated
vendored
Normal file
|
@ -0,0 +1,245 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// String returns a pointer to the provided string
|
||||
func String(value string) *string {
|
||||
return &value
|
||||
}
|
||||
|
||||
// Int returns a pointer to the provided int
|
||||
func Int(value int) *int {
|
||||
return &value
|
||||
}
|
||||
|
||||
// Int64 returns a pointer to the provided int64
|
||||
func Int64(value int64) *int64 {
|
||||
return &value
|
||||
}
|
||||
|
||||
// Uint returns a pointer to the provided uint
|
||||
func Uint(value uint) *uint {
|
||||
return &value
|
||||
}
|
||||
|
||||
//Float32 returns a pointer to the provided float32
|
||||
func Float32(value float32) *float32 {
|
||||
return &value
|
||||
}
|
||||
|
||||
//Float64 returns a pointer to the provided float64
|
||||
func Float64(value float64) *float64 {
|
||||
return &value
|
||||
}
|
||||
|
||||
//Bool returns a pointer to the provided bool
|
||||
func Bool(value bool) *bool {
|
||||
return &value
|
||||
}
|
||||
|
||||
//PointerString prints the values of pointers in a struct
|
||||
//Producing a human friendly string for an struct with pointers.
|
||||
//useful when debugging the values of a struct
|
||||
func PointerString(datastruct interface{}) (representation string) {
|
||||
val := reflect.ValueOf(datastruct)
|
||||
typ := reflect.TypeOf(datastruct)
|
||||
all := make([]string, 2)
|
||||
all = append(all, "{")
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
sf := typ.Field(i)
|
||||
|
||||
//unexported
|
||||
if sf.PkgPath != "" && !sf.Anonymous {
|
||||
continue
|
||||
}
|
||||
|
||||
sv := val.Field(i)
|
||||
stringValue := ""
|
||||
if isNil(sv) {
|
||||
stringValue = fmt.Sprintf("%s=<nil>", sf.Name)
|
||||
} else {
|
||||
if sv.Type().Kind() == reflect.Ptr {
|
||||
sv = sv.Elem()
|
||||
}
|
||||
stringValue = fmt.Sprintf("%s=%v", sf.Name, sv)
|
||||
}
|
||||
all = append(all, stringValue)
|
||||
}
|
||||
all = append(all, "}")
|
||||
representation = strings.TrimSpace(strings.Join(all, " "))
|
||||
return
|
||||
}
|
||||
|
||||
// SDKTime a struct that parses/renders to/from json using RFC339 date-time information
|
||||
type SDKTime struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// SDKDate a struct that parses/renders to/from json using only date information
|
||||
type SDKDate struct {
|
||||
//Date date information
|
||||
Date time.Time
|
||||
}
|
||||
|
||||
func sdkTimeFromTime(t time.Time) SDKTime {
|
||||
return SDKTime{t}
|
||||
}
|
||||
|
||||
func sdkDateFromTime(t time.Time) SDKDate {
|
||||
return SDKDate{Date: t}
|
||||
}
|
||||
|
||||
func formatTime(t SDKTime) string {
|
||||
return t.Format(sdkTimeFormat)
|
||||
}
|
||||
|
||||
func formatDate(t SDKDate) string {
|
||||
return t.Date.Format(sdkDateFormat)
|
||||
}
|
||||
|
||||
func now() *SDKTime {
|
||||
t := SDKTime{time.Now()}
|
||||
return &t
|
||||
}
|
||||
|
||||
var timeType = reflect.TypeOf(SDKTime{})
|
||||
var timeTypePtr = reflect.TypeOf(&SDKTime{})
|
||||
|
||||
var sdkDateType = reflect.TypeOf(SDKDate{})
|
||||
var sdkDateTypePtr = reflect.TypeOf(&SDKDate{})
|
||||
|
||||
//Formats for sdk supported time representations
|
||||
const sdkTimeFormat = time.RFC3339Nano
|
||||
const rfc1123OptionalLeadingDigitsInDay = "Mon, _2 Jan 2006 15:04:05 MST"
|
||||
const sdkDateFormat = "2006-01-02"
|
||||
|
||||
func tryParsingTimeWithValidFormatsForHeaders(data []byte, headerName string) (t time.Time, err error) {
|
||||
header := strings.ToLower(headerName)
|
||||
switch header {
|
||||
case "lastmodified", "date":
|
||||
t, err = tryParsing(data, time.RFC3339Nano, time.RFC3339, time.RFC1123, rfc1123OptionalLeadingDigitsInDay, time.RFC850, time.ANSIC)
|
||||
return
|
||||
default: //By default we parse with RFC3339
|
||||
t, err = time.Parse(sdkTimeFormat, string(data))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func tryParsing(data []byte, layouts ...string) (tm time.Time, err error) {
|
||||
datestring := string(data)
|
||||
for _, l := range layouts {
|
||||
tm, err = time.Parse(l, datestring)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
err = fmt.Errorf("Could not parse time: %s with formats: %s", datestring, layouts[:])
|
||||
return
|
||||
}
|
||||
|
||||
// String returns string representation of SDKDate
|
||||
func (t *SDKDate) String() string {
|
||||
return t.Date.Format(sdkDateFormat)
|
||||
}
|
||||
|
||||
// NewSDKDateFromString parses the dateString into SDKDate
|
||||
func NewSDKDateFromString(dateString string) (*SDKDate, error) {
|
||||
parsedTime, err := time.Parse(sdkDateFormat, dateString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SDKDate{Date: parsedTime}, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals from json
|
||||
func (t *SDKTime) UnmarshalJSON(data []byte) (e error) {
|
||||
s := string(data)
|
||||
if s == "null" {
|
||||
t.Time = time.Time{}
|
||||
} else {
|
||||
//Try parsing with RFC3339
|
||||
t.Time, e = time.Parse(`"`+sdkTimeFormat+`"`, string(data))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalJSON marshals to JSON
|
||||
func (t *SDKTime) MarshalJSON() (buff []byte, e error) {
|
||||
s := t.Format(sdkTimeFormat)
|
||||
buff = []byte(`"` + s + `"`)
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals from json
|
||||
func (t *SDKDate) UnmarshalJSON(data []byte) (e error) {
|
||||
if string(data) == `"null"` {
|
||||
t.Date = time.Time{}
|
||||
return
|
||||
}
|
||||
|
||||
t.Date, e = tryParsing(data,
|
||||
strconv.Quote(sdkDateFormat),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalJSON marshals to JSON
|
||||
func (t *SDKDate) MarshalJSON() (buff []byte, e error) {
|
||||
s := t.Date.Format(sdkDateFormat)
|
||||
buff = []byte(strconv.Quote(s))
|
||||
return
|
||||
}
|
||||
|
||||
// PrivateKeyFromBytes is a helper function that will produce a RSA private
|
||||
// key from bytes.
|
||||
func PrivateKeyFromBytes(pemData []byte, password *string) (key *rsa.PrivateKey, e error) {
|
||||
if pemBlock, _ := pem.Decode(pemData); pemBlock != nil {
|
||||
decrypted := pemBlock.Bytes
|
||||
if x509.IsEncryptedPEMBlock(pemBlock) {
|
||||
if password == nil {
|
||||
e = fmt.Errorf("private_key_password is required for encrypted private keys")
|
||||
return
|
||||
}
|
||||
if decrypted, e = x509.DecryptPEMBlock(pemBlock, []byte(*password)); e != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
key, e = x509.ParsePKCS1PrivateKey(decrypted)
|
||||
|
||||
} else {
|
||||
e = fmt.Errorf("PEM data was not found in buffer")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func generateRandUUID() (string, error) {
|
||||
b := make([]byte, 16)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
uuid := fmt.Sprintf("%x%x%x%x%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
func makeACopy(original []string) []string {
|
||||
tmp := make([]string, len(original))
|
||||
copy(tmp, original)
|
||||
return tmp
|
||||
}
|
961
vendor/github.com/oracle/oci-go-sdk/common/http.go
generated
vendored
Normal file
961
vendor/github.com/oracle/oci-go-sdk/common/http.go
generated
vendored
Normal file
|
@ -0,0 +1,961 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Request Marshaling
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func isNil(v reflect.Value) bool {
|
||||
return v.Kind() == reflect.Ptr && v.IsNil()
|
||||
}
|
||||
|
||||
// Returns the string representation of a reflect.Value
|
||||
// Only transforms primitive values
|
||||
func toStringValue(v reflect.Value, field reflect.StructField) (string, error) {
|
||||
if v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return "", fmt.Errorf("can not marshal a nil pointer")
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
if v.Type() == timeType {
|
||||
t := v.Interface().(SDKTime)
|
||||
return formatTime(t), nil
|
||||
}
|
||||
|
||||
if v.Type() == sdkDateType {
|
||||
t := v.Interface().(SDKDate)
|
||||
return formatDate(t), nil
|
||||
}
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Bool:
|
||||
return strconv.FormatBool(v.Bool()), nil
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return strconv.FormatInt(v.Int(), 10), nil
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return strconv.FormatUint(v.Uint(), 10), nil
|
||||
case reflect.String:
|
||||
return v.String(), nil
|
||||
case reflect.Float32:
|
||||
return strconv.FormatFloat(v.Float(), 'f', 6, 32), nil
|
||||
case reflect.Float64:
|
||||
return strconv.FormatFloat(v.Float(), 'f', 6, 64), nil
|
||||
default:
|
||||
return "", fmt.Errorf("marshaling structure to a http.Request does not support field named: %s of type: %v",
|
||||
field.Name, v.Type().String())
|
||||
}
|
||||
}
|
||||
|
||||
func addBinaryBody(request *http.Request, value reflect.Value) (e error) {
|
||||
readCloser, ok := value.Interface().(io.ReadCloser)
|
||||
if !ok {
|
||||
e = fmt.Errorf("body of the request needs to be an io.ReadCloser interface. Can not marshal body of binary request")
|
||||
return
|
||||
}
|
||||
|
||||
request.Body = readCloser
|
||||
|
||||
//Set the default content type to application/octet-stream if not set
|
||||
if request.Header.Get(requestHeaderContentType) == "" {
|
||||
request.Header.Set(requestHeaderContentType, "application/octet-stream")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getTaggedNilFieldNameOrError, evaluates if a field with json and non mandatory tags is nil
|
||||
// returns the json tag name, or an error if the tags are incorrectly present
|
||||
func getTaggedNilFieldNameOrError(field reflect.StructField, fieldValue reflect.Value) (bool, string, error) {
|
||||
currentTag := field.Tag
|
||||
jsonTag := currentTag.Get("json")
|
||||
|
||||
if jsonTag == "" {
|
||||
return false, "", fmt.Errorf("json tag is not valid for field %s", field.Name)
|
||||
}
|
||||
|
||||
partsJSONTag := strings.Split(jsonTag, ",")
|
||||
nameJSONField := partsJSONTag[0]
|
||||
|
||||
if _, ok := currentTag.Lookup("mandatory"); !ok {
|
||||
//No mandatory field set, no-op
|
||||
return false, nameJSONField, nil
|
||||
}
|
||||
isMandatory, err := strconv.ParseBool(currentTag.Get("mandatory"))
|
||||
if err != nil {
|
||||
return false, "", fmt.Errorf("mandatory tag is not valid for field %s", field.Name)
|
||||
}
|
||||
|
||||
// If the field is marked as mandatory, no-op
|
||||
if isMandatory {
|
||||
return false, nameJSONField, nil
|
||||
}
|
||||
|
||||
Debugf("Adjusting tag: mandatory is false and json tag is valid on field: %s", field.Name)
|
||||
|
||||
// If the field can not be nil, then no-op
|
||||
if !isNillableType(&fieldValue) {
|
||||
Debugf("WARNING json field is tagged with mandatory flags, but the type can not be nil, field name: %s", field.Name)
|
||||
return false, nameJSONField, nil
|
||||
}
|
||||
|
||||
// If field value is nil, tag it as omitEmpty
|
||||
return fieldValue.IsNil(), nameJSONField, nil
|
||||
|
||||
}
|
||||
|
||||
// isNillableType returns true if the filed can be nil
|
||||
func isNillableType(value *reflect.Value) bool {
|
||||
k := value.Kind()
|
||||
switch k {
|
||||
case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// omitNilFieldsInJSON, removes json keys whose struct value is nil, and the field is tagged with the json and
|
||||
// mandatory:false tags
|
||||
func omitNilFieldsInJSON(data interface{}, value reflect.Value) (interface{}, error) {
|
||||
switch value.Kind() {
|
||||
case reflect.Struct:
|
||||
jsonMap := data.(map[string]interface{})
|
||||
fieldType := value.Type()
|
||||
for i := 0; i < fieldType.NumField(); i++ {
|
||||
currentField := fieldType.Field(i)
|
||||
//unexported skip
|
||||
if currentField.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
//Does not have json tag, no-op
|
||||
if _, ok := currentField.Tag.Lookup("json"); !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
currentFieldValue := value.Field(i)
|
||||
ok, jsonFieldName, err := getTaggedNilFieldNameOrError(currentField, currentFieldValue)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can not omit nil fields for field: %s, due to: %s",
|
||||
currentField.Name, err.Error())
|
||||
}
|
||||
|
||||
//Delete the struct field from the json representation
|
||||
if ok {
|
||||
delete(jsonMap, jsonFieldName)
|
||||
continue
|
||||
}
|
||||
|
||||
// Check to make sure the field is part of the json representation of the value
|
||||
if _, contains := jsonMap[jsonFieldName]; !contains {
|
||||
Debugf("Field %s is not present in json, omitting", jsonFieldName)
|
||||
continue
|
||||
}
|
||||
|
||||
if currentFieldValue.Type() == timeType || currentFieldValue.Type() == timeTypePtr ||
|
||||
currentField.Type == sdkDateType || currentField.Type == sdkDateTypePtr {
|
||||
continue
|
||||
}
|
||||
// does it need to be adjusted?
|
||||
var adjustedValue interface{}
|
||||
adjustedValue, err = omitNilFieldsInJSON(jsonMap[jsonFieldName], currentFieldValue)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can not omit nil fields for field: %s, due to: %s",
|
||||
currentField.Name, err.Error())
|
||||
}
|
||||
jsonMap[jsonFieldName] = adjustedValue
|
||||
}
|
||||
return jsonMap, nil
|
||||
case reflect.Slice, reflect.Array:
|
||||
// Special case: a []byte may have been marshalled as a string
|
||||
if data != nil && reflect.TypeOf(data).Kind() == reflect.String && value.Type().Elem().Kind() == reflect.Uint8 {
|
||||
return data, nil
|
||||
}
|
||||
jsonList, ok := data.([]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("can not omit nil fields, data was expected to be a not-nil list")
|
||||
}
|
||||
newList := make([]interface{}, len(jsonList))
|
||||
var err error
|
||||
for i, val := range jsonList {
|
||||
newList[i], err = omitNilFieldsInJSON(val, value.Index(i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return newList, nil
|
||||
case reflect.Map:
|
||||
jsonMap, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("can not omit nil fields, data was expected to be a not-nil map")
|
||||
}
|
||||
newMap := make(map[string]interface{}, len(jsonMap))
|
||||
var err error
|
||||
for key, val := range jsonMap {
|
||||
newMap[key], err = omitNilFieldsInJSON(val, value.MapIndex(reflect.ValueOf(key)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return newMap, nil
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
valPtr := value.Elem()
|
||||
return omitNilFieldsInJSON(data, valPtr)
|
||||
default:
|
||||
//Otherwise no-op
|
||||
return data, nil
|
||||
}
|
||||
}
|
||||
|
||||
// removeNilFieldsInJSONWithTaggedStruct remove struct fields tagged with json and mandatory false
|
||||
// that are nil
|
||||
func removeNilFieldsInJSONWithTaggedStruct(rawJSON []byte, value reflect.Value) ([]byte, error) {
|
||||
var rawInterface interface{}
|
||||
decoder := json.NewDecoder(bytes.NewBuffer(rawJSON))
|
||||
decoder.UseNumber()
|
||||
var err error
|
||||
if err = decoder.Decode(&rawInterface); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fixedMap, err := omitNilFieldsInJSON(rawInterface, value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(fixedMap)
|
||||
}
|
||||
|
||||
func addToBody(request *http.Request, value reflect.Value, field reflect.StructField) (e error) {
|
||||
Debugln("Marshaling to body from field:", field.Name)
|
||||
if request.Body != nil {
|
||||
Logf("The body of the request is already set. Structure: %s will overwrite it\n", field.Name)
|
||||
}
|
||||
tag := field.Tag
|
||||
encoding := tag.Get("encoding")
|
||||
|
||||
if encoding == "binary" {
|
||||
return addBinaryBody(request, value)
|
||||
}
|
||||
|
||||
rawJSON, e := json.Marshal(value.Interface())
|
||||
if e != nil {
|
||||
return
|
||||
}
|
||||
marshaled, e := removeNilFieldsInJSONWithTaggedStruct(rawJSON, value)
|
||||
if e != nil {
|
||||
return
|
||||
}
|
||||
bodyBytes := bytes.NewReader(marshaled)
|
||||
request.ContentLength = int64(bodyBytes.Len())
|
||||
request.Header.Set(requestHeaderContentLength, strconv.FormatInt(request.ContentLength, 10))
|
||||
request.Header.Set(requestHeaderContentType, "application/json")
|
||||
request.Body = ioutil.NopCloser(bodyBytes)
|
||||
request.GetBody = func() (io.ReadCloser, error) {
|
||||
return ioutil.NopCloser(bodyBytes), nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func addToQuery(request *http.Request, value reflect.Value, field reflect.StructField) (e error) {
|
||||
Debugln("Marshaling to query from field: ", field.Name)
|
||||
if request.URL == nil {
|
||||
request.URL = &url.URL{}
|
||||
}
|
||||
query := request.URL.Query()
|
||||
var queryParameterValue, queryParameterName string
|
||||
|
||||
if queryParameterName = field.Tag.Get("name"); queryParameterName == "" {
|
||||
return fmt.Errorf("marshaling request to a query requires the 'name' tag for field: %s ", field.Name)
|
||||
}
|
||||
|
||||
mandatory, _ := strconv.ParseBool(strings.ToLower(field.Tag.Get("mandatory")))
|
||||
|
||||
//If mandatory and nil. Error out
|
||||
if mandatory && isNil(value) {
|
||||
return fmt.Errorf("marshaling request to a header requires not nil pointer for field: %s", field.Name)
|
||||
}
|
||||
|
||||
//if not mandatory and nil. Omit
|
||||
if !mandatory && isNil(value) {
|
||||
Debugf("Query parameter value is not mandatory and is nil pointer in field: %s. Skipping query", field.Name)
|
||||
return
|
||||
}
|
||||
|
||||
encoding := strings.ToLower(field.Tag.Get("collectionFormat"))
|
||||
var collectionFormatStringValues []string
|
||||
switch encoding {
|
||||
case "csv", "multi":
|
||||
if value.Kind() != reflect.Slice && value.Kind() != reflect.Array {
|
||||
e = fmt.Errorf("query parameter is tagged as csv or multi yet its type is neither an Array nor a Slice: %s", field.Name)
|
||||
break
|
||||
}
|
||||
|
||||
numOfElements := value.Len()
|
||||
collectionFormatStringValues = make([]string, numOfElements)
|
||||
for i := 0; i < numOfElements; i++ {
|
||||
collectionFormatStringValues[i], e = toStringValue(value.Index(i), field)
|
||||
if e != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
queryParameterValue = strings.Join(collectionFormatStringValues, ",")
|
||||
case "":
|
||||
queryParameterValue, e = toStringValue(value, field)
|
||||
default:
|
||||
e = fmt.Errorf("encoding of type %s is not supported for query param: %s", encoding, field.Name)
|
||||
}
|
||||
|
||||
if e != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//check for tag "omitEmpty", this is done to accomodate unset fields that do not
|
||||
//support an empty string: enums in query params
|
||||
if omitEmpty, present := field.Tag.Lookup("omitEmpty"); present {
|
||||
omitEmptyBool, _ := strconv.ParseBool(strings.ToLower(omitEmpty))
|
||||
if queryParameterValue != "" || !omitEmptyBool {
|
||||
addToQueryForEncoding(&query, encoding, queryParameterName, queryParameterValue, collectionFormatStringValues)
|
||||
} else {
|
||||
Debugf("Omitting %s, is empty and omitEmpty tag is set", field.Name)
|
||||
}
|
||||
} else {
|
||||
addToQueryForEncoding(&query, encoding, queryParameterName, queryParameterValue, collectionFormatStringValues)
|
||||
}
|
||||
|
||||
request.URL.RawQuery = query.Encode()
|
||||
return
|
||||
}
|
||||
|
||||
func addToQueryForEncoding(query *url.Values, encoding string, queryParameterName string, queryParameterValue string, collectionFormatStringValues []string) {
|
||||
if encoding == "multi" {
|
||||
for _, stringValue := range collectionFormatStringValues {
|
||||
query.Add(queryParameterName, stringValue)
|
||||
}
|
||||
} else {
|
||||
query.Set(queryParameterName, queryParameterValue)
|
||||
}
|
||||
}
|
||||
|
||||
// Adds to the path of the url in the order they appear in the structure
|
||||
func addToPath(request *http.Request, value reflect.Value, field reflect.StructField) (e error) {
|
||||
var additionalURLPathPart string
|
||||
if additionalURLPathPart, e = toStringValue(value, field); e != nil {
|
||||
return fmt.Errorf("can not marshal to path in request for field %s. Due to %s", field.Name, e.Error())
|
||||
}
|
||||
|
||||
// path should not be empty for any operations
|
||||
if len(additionalURLPathPart) == 0 {
|
||||
return fmt.Errorf("value cannot be empty for field %s in path", field.Name)
|
||||
}
|
||||
|
||||
if request.URL == nil {
|
||||
request.URL = &url.URL{}
|
||||
request.URL.Path = ""
|
||||
}
|
||||
var currentURLPath = request.URL.Path
|
||||
|
||||
var templatedPathRegex, _ = regexp.Compile(".*{.+}.*")
|
||||
if !templatedPathRegex.MatchString(currentURLPath) {
|
||||
Debugln("Marshaling request to path by appending field:", field.Name)
|
||||
allPath := []string{currentURLPath, additionalURLPathPart}
|
||||
request.URL.Path = strings.Join(allPath, "/")
|
||||
} else {
|
||||
var fieldName string
|
||||
if fieldName = field.Tag.Get("name"); fieldName == "" {
|
||||
e = fmt.Errorf("marshaling request to path name and template requires a 'name' tag for field: %s", field.Name)
|
||||
return
|
||||
}
|
||||
urlTemplate := currentURLPath
|
||||
Debugln("Marshaling to path from field: ", field.Name, " in template: ", urlTemplate)
|
||||
request.URL.Path = strings.Replace(urlTemplate, "{"+fieldName+"}", additionalURLPathPart, -1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setWellKnownHeaders(request *http.Request, headerName, headerValue string) (e error) {
|
||||
switch strings.ToLower(headerName) {
|
||||
case "content-length":
|
||||
var len int
|
||||
len, e = strconv.Atoi(headerValue)
|
||||
if e != nil {
|
||||
return
|
||||
}
|
||||
request.ContentLength = int64(len)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addToHeader(request *http.Request, value reflect.Value, field reflect.StructField) (e error) {
|
||||
Debugln("Marshaling to header from field: ", field.Name)
|
||||
if request.Header == nil {
|
||||
request.Header = http.Header{}
|
||||
}
|
||||
|
||||
var headerName, headerValue string
|
||||
if headerName = field.Tag.Get("name"); headerName == "" {
|
||||
return fmt.Errorf("marshaling request to a header requires the 'name' tag for field: %s", field.Name)
|
||||
}
|
||||
|
||||
mandatory, _ := strconv.ParseBool(strings.ToLower(field.Tag.Get("mandatory")))
|
||||
//If mandatory and nil. Error out
|
||||
if mandatory && isNil(value) {
|
||||
return fmt.Errorf("marshaling request to a header requires not nil pointer for field: %s", field.Name)
|
||||
}
|
||||
|
||||
// generate opc-request-id if header value is nil and header name matches
|
||||
value = generateOpcRequestID(headerName, value)
|
||||
|
||||
//if not mandatory and nil. Omit
|
||||
if !mandatory && isNil(value) {
|
||||
Debugf("Header value is not mandatory and is nil pointer in field: %s. Skipping header", field.Name)
|
||||
return
|
||||
}
|
||||
|
||||
//Otherwise get value and set header
|
||||
if headerValue, e = toStringValue(value, field); e != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if e = setWellKnownHeaders(request, headerName, headerValue); e != nil {
|
||||
return
|
||||
}
|
||||
|
||||
request.Header.Add(headerName, headerValue)
|
||||
return
|
||||
}
|
||||
|
||||
// Header collection is a map of string to string that gets rendered as individual headers with a given prefix
|
||||
func addToHeaderCollection(request *http.Request, value reflect.Value, field reflect.StructField) (e error) {
|
||||
Debugln("Marshaling to header-collection from field:", field.Name)
|
||||
if request.Header == nil {
|
||||
request.Header = http.Header{}
|
||||
}
|
||||
|
||||
var headerPrefix string
|
||||
if headerPrefix = field.Tag.Get("prefix"); headerPrefix == "" {
|
||||
return fmt.Errorf("marshaling request to a header requires the 'prefix' tag for field: %s", field.Name)
|
||||
}
|
||||
|
||||
mandatory, _ := strconv.ParseBool(strings.ToLower(field.Tag.Get("mandatory")))
|
||||
//If mandatory and nil. Error out
|
||||
if mandatory && isNil(value) {
|
||||
return fmt.Errorf("marshaling request to a header requires not nil pointer for field: %s", field.Name)
|
||||
}
|
||||
|
||||
//if not mandatory and nil. Omit
|
||||
if !mandatory && isNil(value) {
|
||||
Debugf("Header value is not mandatory and is nil pointer in field: %s. Skipping header", field.Name)
|
||||
return
|
||||
}
|
||||
|
||||
//cast to map
|
||||
headerValues, ok := value.Interface().(map[string]string)
|
||||
if !ok {
|
||||
e = fmt.Errorf("header fields need to be of type map[string]string")
|
||||
return
|
||||
}
|
||||
|
||||
for k, v := range headerValues {
|
||||
headerName := fmt.Sprintf("%s%s", headerPrefix, k)
|
||||
request.Header.Set(headerName, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Makes sure the incoming structure is able to be marshalled
|
||||
// to a request
|
||||
func checkForValidRequestStruct(s interface{}) (*reflect.Value, error) {
|
||||
val := reflect.ValueOf(s)
|
||||
for val.Kind() == reflect.Ptr {
|
||||
if val.IsNil() {
|
||||
return nil, fmt.Errorf("can not marshal to request a pointer to structure")
|
||||
}
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if s == nil {
|
||||
return nil, fmt.Errorf("can not marshal to request a nil structure")
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("can not marshal to request, expects struct input. Got %v", val.Kind())
|
||||
}
|
||||
|
||||
return &val, nil
|
||||
}
|
||||
|
||||
// Populates the parts of a request by reading tags in the passed structure
|
||||
// nested structs are followed recursively depth-first.
|
||||
func structToRequestPart(request *http.Request, val reflect.Value) (err error) {
|
||||
typ := val.Type()
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sf := typ.Field(i)
|
||||
//unexported
|
||||
if sf.PkgPath != "" && !sf.Anonymous {
|
||||
continue
|
||||
}
|
||||
|
||||
sv := val.Field(i)
|
||||
tag := sf.Tag.Get("contributesTo")
|
||||
switch tag {
|
||||
case "header":
|
||||
err = addToHeader(request, sv, sf)
|
||||
case "header-collection":
|
||||
err = addToHeaderCollection(request, sv, sf)
|
||||
case "path":
|
||||
err = addToPath(request, sv, sf)
|
||||
case "query":
|
||||
err = addToQuery(request, sv, sf)
|
||||
case "body":
|
||||
err = addToBody(request, sv, sf)
|
||||
case "":
|
||||
Debugln(sf.Name, " does not contain contributes tag. Skipping.")
|
||||
default:
|
||||
err = fmt.Errorf("can not marshal field: %s. It needs to contain valid contributesTo tag", sf.Name)
|
||||
}
|
||||
}
|
||||
|
||||
//If headers are and the content type was not set, we default to application/json
|
||||
if request.Header != nil && request.Header.Get(requestHeaderContentType) == "" {
|
||||
request.Header.Set(requestHeaderContentType, "application/json")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// HTTPRequestMarshaller marshals a structure to an http request using tag values in the struct
|
||||
// The marshaller tag should like the following
|
||||
// type A struct {
|
||||
// ANumber string `contributesTo="query" name="number"`
|
||||
// TheBody `contributesTo="body"`
|
||||
// }
|
||||
// where the contributesTo tag can be: header, path, query, body
|
||||
// and the 'name' tag is the name of the value used in the http request(not applicable for path)
|
||||
// If path is specified as part of the tag, the values are appened to the url path
|
||||
// in the order they appear in the structure
|
||||
// The current implementation only supports primitive types, except for the body tag, which needs a struct type.
|
||||
// The body of a request will be marshaled using the tags of the structure
|
||||
func HTTPRequestMarshaller(requestStruct interface{}, httpRequest *http.Request) (err error) {
|
||||
var val *reflect.Value
|
||||
if val, err = checkForValidRequestStruct(requestStruct); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
Debugln("Marshaling to Request: ", val.Type().Name())
|
||||
err = structToRequestPart(httpRequest, *val)
|
||||
return
|
||||
}
|
||||
|
||||
// MakeDefaultHTTPRequest creates the basic http request with the necessary headers set
|
||||
func MakeDefaultHTTPRequest(method, path string) (httpRequest http.Request) {
|
||||
httpRequest = http.Request{
|
||||
Proto: "HTTP/1.1",
|
||||
ProtoMajor: 1,
|
||||
ProtoMinor: 1,
|
||||
Header: make(http.Header),
|
||||
URL: &url.URL{},
|
||||
}
|
||||
|
||||
httpRequest.Header.Set(requestHeaderContentLength, "0")
|
||||
httpRequest.Header.Set(requestHeaderDate, time.Now().UTC().Format(http.TimeFormat))
|
||||
httpRequest.Header.Set(requestHeaderOpcClientInfo, strings.Join([]string{defaultSDKMarker, Version()}, "/"))
|
||||
httpRequest.Header.Set(requestHeaderAccept, "*/*")
|
||||
httpRequest.Method = method
|
||||
httpRequest.URL.Path = path
|
||||
return
|
||||
}
|
||||
|
||||
// MakeDefaultHTTPRequestWithTaggedStruct creates an http request from an struct with tagged fields, see HTTPRequestMarshaller
|
||||
// for more information
|
||||
func MakeDefaultHTTPRequestWithTaggedStruct(method, path string, requestStruct interface{}) (httpRequest http.Request, err error) {
|
||||
httpRequest = MakeDefaultHTTPRequest(method, path)
|
||||
err = HTTPRequestMarshaller(requestStruct, &httpRequest)
|
||||
return
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Request UnMarshaling
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Makes sure the incoming structure is able to be unmarshaled
|
||||
// to a request
|
||||
func checkForValidResponseStruct(s interface{}) (*reflect.Value, error) {
|
||||
val := reflect.ValueOf(s)
|
||||
for val.Kind() == reflect.Ptr {
|
||||
if val.IsNil() {
|
||||
return nil, fmt.Errorf("can not unmarshal to response a pointer to nil structure")
|
||||
}
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if s == nil {
|
||||
return nil, fmt.Errorf("can not unmarshal to response a nil structure")
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("can not unmarshal to response, expects struct input. Got %v", val.Kind())
|
||||
}
|
||||
|
||||
return &val, nil
|
||||
}
|
||||
|
||||
func intSizeFromKind(kind reflect.Kind) int {
|
||||
switch kind {
|
||||
case reflect.Int8, reflect.Uint8:
|
||||
return 8
|
||||
case reflect.Int16, reflect.Uint16:
|
||||
return 16
|
||||
case reflect.Int32, reflect.Uint32:
|
||||
return 32
|
||||
case reflect.Int64, reflect.Uint64:
|
||||
return 64
|
||||
case reflect.Int, reflect.Uint:
|
||||
return strconv.IntSize
|
||||
default:
|
||||
Debugf("The type is not valid: %v. Returing int size for arch\n", kind.String())
|
||||
return strconv.IntSize
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func analyzeValue(stringValue string, kind reflect.Kind, field reflect.StructField) (val reflect.Value, valPointer reflect.Value, err error) {
|
||||
switch kind {
|
||||
case timeType.Kind():
|
||||
var t time.Time
|
||||
t, err = tryParsingTimeWithValidFormatsForHeaders([]byte(stringValue), field.Name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sdkTime := sdkTimeFromTime(t)
|
||||
val = reflect.ValueOf(sdkTime)
|
||||
valPointer = reflect.ValueOf(&sdkTime)
|
||||
return
|
||||
case sdkDateType.Kind():
|
||||
var t time.Time
|
||||
t, err = tryParsingTimeWithValidFormatsForHeaders([]byte(stringValue), field.Name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sdkDate := sdkDateFromTime(t)
|
||||
val = reflect.ValueOf(sdkDate)
|
||||
valPointer = reflect.ValueOf(&sdkDate)
|
||||
return
|
||||
case reflect.Bool:
|
||||
var bVal bool
|
||||
if bVal, err = strconv.ParseBool(stringValue); err != nil {
|
||||
return
|
||||
}
|
||||
val = reflect.ValueOf(bVal)
|
||||
valPointer = reflect.ValueOf(&bVal)
|
||||
return
|
||||
case reflect.Int:
|
||||
size := intSizeFromKind(kind)
|
||||
var iVal int64
|
||||
if iVal, err = strconv.ParseInt(stringValue, 10, size); err != nil {
|
||||
return
|
||||
}
|
||||
var iiVal int
|
||||
iiVal = int(iVal)
|
||||
val = reflect.ValueOf(iiVal)
|
||||
valPointer = reflect.ValueOf(&iiVal)
|
||||
return
|
||||
case reflect.Int64:
|
||||
size := intSizeFromKind(kind)
|
||||
var iVal int64
|
||||
if iVal, err = strconv.ParseInt(stringValue, 10, size); err != nil {
|
||||
return
|
||||
}
|
||||
val = reflect.ValueOf(iVal)
|
||||
valPointer = reflect.ValueOf(&iVal)
|
||||
return
|
||||
case reflect.Uint:
|
||||
size := intSizeFromKind(kind)
|
||||
var iVal uint64
|
||||
if iVal, err = strconv.ParseUint(stringValue, 10, size); err != nil {
|
||||
return
|
||||
}
|
||||
var uiVal uint
|
||||
uiVal = uint(iVal)
|
||||
val = reflect.ValueOf(uiVal)
|
||||
valPointer = reflect.ValueOf(&uiVal)
|
||||
return
|
||||
case reflect.String:
|
||||
val = reflect.ValueOf(stringValue)
|
||||
valPointer = reflect.ValueOf(&stringValue)
|
||||
case reflect.Float32:
|
||||
var fVal float64
|
||||
if fVal, err = strconv.ParseFloat(stringValue, 32); err != nil {
|
||||
return
|
||||
}
|
||||
var ffVal float32
|
||||
ffVal = float32(fVal)
|
||||
val = reflect.ValueOf(ffVal)
|
||||
valPointer = reflect.ValueOf(&ffVal)
|
||||
return
|
||||
case reflect.Float64:
|
||||
var fVal float64
|
||||
if fVal, err = strconv.ParseFloat(stringValue, 64); err != nil {
|
||||
return
|
||||
}
|
||||
val = reflect.ValueOf(fVal)
|
||||
valPointer = reflect.ValueOf(&fVal)
|
||||
return
|
||||
default:
|
||||
err = fmt.Errorf("value for kind: %s not supported", kind)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Sets the field of a struct, with the appropiate value of the string
|
||||
// Only sets basic types
|
||||
func fromStringValue(newValue string, val *reflect.Value, field reflect.StructField) (err error) {
|
||||
|
||||
if !val.CanSet() {
|
||||
err = fmt.Errorf("can not set field name: %s of type: %v", field.Name, val.Type().String())
|
||||
return
|
||||
}
|
||||
|
||||
kind := val.Kind()
|
||||
isPointer := false
|
||||
if val.Kind() == reflect.Ptr {
|
||||
isPointer = true
|
||||
kind = field.Type.Elem().Kind()
|
||||
}
|
||||
|
||||
value, valPtr, err := analyzeValue(newValue, kind, field)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !isPointer {
|
||||
val.Set(value)
|
||||
} else {
|
||||
val.Set(valPtr)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// PolymorphicJSONUnmarshaler is the interface to unmarshal polymorphic json payloads
|
||||
type PolymorphicJSONUnmarshaler interface {
|
||||
UnmarshalPolymorphicJSON(data []byte) (interface{}, error)
|
||||
}
|
||||
|
||||
func valueFromPolymorphicJSON(content []byte, unmarshaler PolymorphicJSONUnmarshaler) (val interface{}, err error) {
|
||||
err = json.Unmarshal(content, unmarshaler)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
val, err = unmarshaler.UnmarshalPolymorphicJSON(content)
|
||||
return
|
||||
}
|
||||
|
||||
func valueFromJSONBody(response *http.Response, value *reflect.Value, unmarshaler PolymorphicJSONUnmarshaler) (val interface{}, err error) {
|
||||
//Consumes the body, consider implementing it
|
||||
//without body consumption
|
||||
var content []byte
|
||||
content, err = ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if unmarshaler != nil {
|
||||
val, err = valueFromPolymorphicJSON(content, unmarshaler)
|
||||
return
|
||||
}
|
||||
|
||||
val = reflect.New(value.Type()).Interface()
|
||||
err = json.Unmarshal(content, &val)
|
||||
return
|
||||
}
|
||||
|
||||
func addFromBody(response *http.Response, value *reflect.Value, field reflect.StructField, unmarshaler PolymorphicJSONUnmarshaler) (err error) {
|
||||
Debugln("Unmarshaling from body to field: ", field.Name)
|
||||
if response.Body == nil {
|
||||
Debugln("Unmarshaling body skipped due to nil body content for field: ", field.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
tag := field.Tag
|
||||
encoding := tag.Get("encoding")
|
||||
var iVal interface{}
|
||||
switch encoding {
|
||||
case "binary":
|
||||
value.Set(reflect.ValueOf(response.Body))
|
||||
return
|
||||
case "plain-text":
|
||||
//Expects UTF-8
|
||||
byteArr, e := ioutil.ReadAll(response.Body)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
str := string(byteArr)
|
||||
value.Set(reflect.ValueOf(&str))
|
||||
return
|
||||
default: //If the encoding is not set. we'll decode with json
|
||||
iVal, err = valueFromJSONBody(response, value, unmarshaler)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
newVal := reflect.ValueOf(iVal)
|
||||
if newVal.Kind() == reflect.Ptr {
|
||||
newVal = newVal.Elem()
|
||||
}
|
||||
value.Set(newVal)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func addFromHeader(response *http.Response, value *reflect.Value, field reflect.StructField) (err error) {
|
||||
Debugln("Unmarshaling from header to field: ", field.Name)
|
||||
var headerName string
|
||||
if headerName = field.Tag.Get("name"); headerName == "" {
|
||||
return fmt.Errorf("unmarshaling response to a header requires the 'name' tag for field: %s", field.Name)
|
||||
}
|
||||
|
||||
headerValue := response.Header.Get(headerName)
|
||||
if headerValue == "" {
|
||||
Debugf("Unmarshalling did not find header with name:%s", headerName)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = fromStringValue(headerValue, value, field); err != nil {
|
||||
return fmt.Errorf("unmarshaling response to a header failed for field %s, due to %s", field.Name,
|
||||
err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func addFromHeaderCollection(response *http.Response, value *reflect.Value, field reflect.StructField) error {
|
||||
Debugln("Unmarshaling from header-collection to field:", field.Name)
|
||||
var headerPrefix string
|
||||
if headerPrefix = field.Tag.Get("prefix"); headerPrefix == "" {
|
||||
return fmt.Errorf("Unmarshaling response to a header-collection requires the 'prefix' tag for field: %s", field.Name)
|
||||
}
|
||||
|
||||
mapCollection := make(map[string]string)
|
||||
for name, value := range response.Header {
|
||||
nameLowerCase := strings.ToLower(name)
|
||||
if strings.HasPrefix(nameLowerCase, headerPrefix) {
|
||||
headerNoPrefix := strings.TrimPrefix(nameLowerCase, headerPrefix)
|
||||
mapCollection[headerNoPrefix] = value[0]
|
||||
}
|
||||
}
|
||||
|
||||
Debugln("Marshalled header collection is:", mapCollection)
|
||||
value.Set(reflect.ValueOf(mapCollection))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Populates a struct from parts of a request by reading tags of the struct
|
||||
func responseToStruct(response *http.Response, val *reflect.Value, unmarshaler PolymorphicJSONUnmarshaler) (err error) {
|
||||
typ := val.Type()
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sf := typ.Field(i)
|
||||
|
||||
//unexported
|
||||
if sf.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
sv := val.Field(i)
|
||||
tag := sf.Tag.Get("presentIn")
|
||||
switch tag {
|
||||
case "header":
|
||||
err = addFromHeader(response, &sv, sf)
|
||||
case "header-collection":
|
||||
err = addFromHeaderCollection(response, &sv, sf)
|
||||
case "body":
|
||||
err = addFromBody(response, &sv, sf, unmarshaler)
|
||||
case "":
|
||||
Debugln(sf.Name, " does not contain presentIn tag. Skipping")
|
||||
default:
|
||||
err = fmt.Errorf("can not unmarshal field: %s. It needs to contain valid presentIn tag", sf.Name)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalResponse hydrates the fields of a struct with the values of a http response, guided
|
||||
// by the field tags. The directive tag is "presentIn" and it can be either
|
||||
// - "header": Will look for the header tagged as "name" in the headers of the struct and set it value to that
|
||||
// - "body": It will try to marshal the body from a json string to a struct tagged with 'presentIn: "body"'.
|
||||
// Further this method will consume the body it should be safe to close it after this function
|
||||
// Notice the current implementation only supports native types:int, strings, floats, bool as the field types
|
||||
func UnmarshalResponse(httpResponse *http.Response, responseStruct interface{}) (err error) {
|
||||
|
||||
var val *reflect.Value
|
||||
if val, err = checkForValidResponseStruct(responseStruct); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = responseToStruct(httpResponse, val, nil); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalResponseWithPolymorphicBody similar to UnmarshalResponse but assumes the body of the response
|
||||
// contains polymorphic json. This function will use the unmarshaler argument to unmarshal json content
|
||||
func UnmarshalResponseWithPolymorphicBody(httpResponse *http.Response, responseStruct interface{}, unmarshaler PolymorphicJSONUnmarshaler) (err error) {
|
||||
|
||||
var val *reflect.Value
|
||||
if val, err = checkForValidResponseStruct(responseStruct); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = responseToStruct(httpResponse, val, unmarshaler); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// generate request id if user not provided and for each retry operation re-gen a new request id
|
||||
func generateOpcRequestID(headerName string, value reflect.Value) (newValue reflect.Value) {
|
||||
newValue = value
|
||||
isNilValue := isNil(newValue)
|
||||
isOpcRequestIDHeader := headerName == requestHeaderOpcRequestID || headerName == requestHeaderOpcClientRequestID
|
||||
|
||||
if isNilValue && isOpcRequestIDHeader {
|
||||
requestID, err := generateRandUUID()
|
||||
|
||||
if err != nil {
|
||||
// this will not fail the request, just skip add opc-request-id
|
||||
Debugf("unable to generate opc-request-id. %s", err.Error())
|
||||
} else {
|
||||
newValue = reflect.ValueOf(String(requestID))
|
||||
Debugf("add request id for header: %s, with value: %s", headerName, requestID)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
269
vendor/github.com/oracle/oci-go-sdk/common/http_signer.go
generated
vendored
Normal file
269
vendor/github.com/oracle/oci-go-sdk/common/http_signer.go
generated
vendored
Normal file
|
@ -0,0 +1,269 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// HTTPRequestSigner the interface to sign a request
|
||||
type HTTPRequestSigner interface {
|
||||
Sign(r *http.Request) error
|
||||
}
|
||||
|
||||
// KeyProvider interface that wraps information about the key's account owner
|
||||
type KeyProvider interface {
|
||||
PrivateRSAKey() (*rsa.PrivateKey, error)
|
||||
KeyID() (string, error)
|
||||
}
|
||||
|
||||
const signerVersion = "1"
|
||||
|
||||
// SignerBodyHashPredicate a function that allows to disable/enable body hashing
|
||||
// of requests and headers associated with body content
|
||||
type SignerBodyHashPredicate func(r *http.Request) bool
|
||||
|
||||
// ociRequestSigner implements the http-signatures-draft spec
|
||||
// as described in https://tools.ietf.org/html/draft-cavage-http-signatures-08
|
||||
type ociRequestSigner struct {
|
||||
KeyProvider KeyProvider
|
||||
GenericHeaders []string
|
||||
BodyHeaders []string
|
||||
ShouldHashBody SignerBodyHashPredicate
|
||||
}
|
||||
|
||||
var (
|
||||
defaultGenericHeaders = []string{"date", "(request-target)", "host"}
|
||||
defaultBodyHeaders = []string{"content-length", "content-type", "x-content-sha256"}
|
||||
defaultBodyHashPredicate = func(r *http.Request) bool {
|
||||
return r.Method == http.MethodPost || r.Method == http.MethodPut || r.Method == http.MethodPatch
|
||||
}
|
||||
)
|
||||
|
||||
// DefaultGenericHeaders list of default generic headers that is used in signing
|
||||
func DefaultGenericHeaders() []string {
|
||||
return makeACopy(defaultGenericHeaders)
|
||||
}
|
||||
|
||||
// DefaultBodyHeaders list of default body headers that is used in signing
|
||||
func DefaultBodyHeaders() []string {
|
||||
return makeACopy(defaultBodyHeaders)
|
||||
}
|
||||
|
||||
// DefaultRequestSigner creates a signer with default parameters.
|
||||
func DefaultRequestSigner(provider KeyProvider) HTTPRequestSigner {
|
||||
return RequestSigner(provider, defaultGenericHeaders, defaultBodyHeaders)
|
||||
}
|
||||
|
||||
// RequestSignerExcludeBody creates a signer without hash the body.
|
||||
func RequestSignerExcludeBody(provider KeyProvider) HTTPRequestSigner {
|
||||
bodyHashPredicate := func(r *http.Request) bool {
|
||||
// week request signer will not hash the body
|
||||
return false
|
||||
}
|
||||
return RequestSignerWithBodyHashingPredicate(provider, defaultGenericHeaders, defaultBodyHeaders, bodyHashPredicate)
|
||||
}
|
||||
|
||||
// NewSignerFromOCIRequestSigner creates a copy of the request signer and attaches the new SignerBodyHashPredicate
|
||||
// returns an error if the passed signer is not of type ociRequestSigner
|
||||
func NewSignerFromOCIRequestSigner(oldSigner HTTPRequestSigner, predicate SignerBodyHashPredicate) (HTTPRequestSigner, error) {
|
||||
if oldS, ok := oldSigner.(ociRequestSigner); ok {
|
||||
s := ociRequestSigner{
|
||||
KeyProvider: oldS.KeyProvider,
|
||||
GenericHeaders: oldS.GenericHeaders,
|
||||
BodyHeaders: oldS.BodyHeaders,
|
||||
ShouldHashBody: predicate,
|
||||
}
|
||||
return s, nil
|
||||
|
||||
}
|
||||
return nil, fmt.Errorf("can not create a signer, input signer needs to be of type ociRequestSigner")
|
||||
}
|
||||
|
||||
// RequestSigner creates a signer that utilizes the specified headers for signing
|
||||
// and the default predicate for using the body of the request as part of the signature
|
||||
func RequestSigner(provider KeyProvider, genericHeaders, bodyHeaders []string) HTTPRequestSigner {
|
||||
return ociRequestSigner{
|
||||
KeyProvider: provider,
|
||||
GenericHeaders: genericHeaders,
|
||||
BodyHeaders: bodyHeaders,
|
||||
ShouldHashBody: defaultBodyHashPredicate}
|
||||
}
|
||||
|
||||
// RequestSignerWithBodyHashingPredicate creates a signer that utilizes the specified headers for signing, as well as a predicate for using
|
||||
// the body of the request and bodyHeaders parameter as part of the signature
|
||||
func RequestSignerWithBodyHashingPredicate(provider KeyProvider, genericHeaders, bodyHeaders []string, shouldHashBody SignerBodyHashPredicate) HTTPRequestSigner {
|
||||
return ociRequestSigner{
|
||||
KeyProvider: provider,
|
||||
GenericHeaders: genericHeaders,
|
||||
BodyHeaders: bodyHeaders,
|
||||
ShouldHashBody: shouldHashBody}
|
||||
}
|
||||
|
||||
func (signer ociRequestSigner) getSigningHeaders(r *http.Request) []string {
|
||||
var result []string
|
||||
result = append(result, signer.GenericHeaders...)
|
||||
|
||||
if signer.ShouldHashBody(r) {
|
||||
result = append(result, signer.BodyHeaders...)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (signer ociRequestSigner) getSigningString(request *http.Request) string {
|
||||
signingHeaders := signer.getSigningHeaders(request)
|
||||
signingParts := make([]string, len(signingHeaders))
|
||||
for i, part := range signingHeaders {
|
||||
var value string
|
||||
part = strings.ToLower(part)
|
||||
switch part {
|
||||
case "(request-target)":
|
||||
value = getRequestTarget(request)
|
||||
case "host":
|
||||
value = request.URL.Host
|
||||
if len(value) == 0 {
|
||||
value = request.Host
|
||||
}
|
||||
default:
|
||||
value = request.Header.Get(part)
|
||||
}
|
||||
signingParts[i] = fmt.Sprintf("%s: %s", part, value)
|
||||
}
|
||||
|
||||
signingString := strings.Join(signingParts, "\n")
|
||||
return signingString
|
||||
|
||||
}
|
||||
|
||||
func getRequestTarget(request *http.Request) string {
|
||||
lowercaseMethod := strings.ToLower(request.Method)
|
||||
return fmt.Sprintf("%s %s", lowercaseMethod, request.URL.RequestURI())
|
||||
}
|
||||
|
||||
func calculateHashOfBody(request *http.Request) (err error) {
|
||||
var hash string
|
||||
hash, err = GetBodyHash(request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
request.Header.Set(requestHeaderXContentSHA256, hash)
|
||||
return
|
||||
}
|
||||
|
||||
// drainBody reads all of b to memory and then returns two equivalent
|
||||
// ReadClosers yielding the same bytes.
|
||||
//
|
||||
// It returns an error if the initial slurp of all bytes fails. It does not attempt
|
||||
// to make the returned ReadClosers have identical error-matching behavior.
|
||||
func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) {
|
||||
if b == http.NoBody {
|
||||
// No copying needed. Preserve the magic sentinel meaning of NoBody.
|
||||
return http.NoBody, http.NoBody, nil
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if _, err = buf.ReadFrom(b); err != nil {
|
||||
return nil, b, err
|
||||
}
|
||||
if err = b.Close(); err != nil {
|
||||
return nil, b, err
|
||||
}
|
||||
return ioutil.NopCloser(&buf), ioutil.NopCloser(bytes.NewReader(buf.Bytes())), nil
|
||||
}
|
||||
|
||||
func hashAndEncode(data []byte) string {
|
||||
hashedContent := sha256.Sum256(data)
|
||||
hash := base64.StdEncoding.EncodeToString(hashedContent[:])
|
||||
return hash
|
||||
}
|
||||
|
||||
// GetBodyHash creates a base64 string from the hash of body the request
|
||||
func GetBodyHash(request *http.Request) (hashString string, err error) {
|
||||
if request.Body == nil {
|
||||
request.ContentLength = 0
|
||||
request.Header.Set(requestHeaderContentLength, fmt.Sprintf("%v", request.ContentLength))
|
||||
return hashAndEncode([]byte("")), nil
|
||||
}
|
||||
|
||||
var data []byte
|
||||
bReader := request.Body
|
||||
bReader, request.Body, err = drainBody(request.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("can not read body of request while calculating body hash: %s", err.Error())
|
||||
}
|
||||
|
||||
data, err = ioutil.ReadAll(bReader)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("can not read body of request while calculating body hash: %s", err.Error())
|
||||
}
|
||||
|
||||
// Since the request can be coming from a binary body. Make an attempt to set the body length
|
||||
request.ContentLength = int64(len(data))
|
||||
request.Header.Set(requestHeaderContentLength, fmt.Sprintf("%v", request.ContentLength))
|
||||
|
||||
hashString = hashAndEncode(data)
|
||||
return
|
||||
}
|
||||
|
||||
func (signer ociRequestSigner) computeSignature(request *http.Request) (signature string, err error) {
|
||||
signingString := signer.getSigningString(request)
|
||||
hasher := sha256.New()
|
||||
hasher.Write([]byte(signingString))
|
||||
hashed := hasher.Sum(nil)
|
||||
|
||||
privateKey, err := signer.KeyProvider.PrivateRSAKey()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var unencodedSig []byte
|
||||
unencodedSig, e := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("can not compute signature while signing the request %s: ", e.Error())
|
||||
return
|
||||
}
|
||||
|
||||
signature = base64.StdEncoding.EncodeToString(unencodedSig)
|
||||
return
|
||||
}
|
||||
|
||||
// Sign signs the http request, by inspecting the necessary headers. Once signed
|
||||
// the request will have the proper 'Authorization' header set, otherwise
|
||||
// and error is returned
|
||||
func (signer ociRequestSigner) Sign(request *http.Request) (err error) {
|
||||
if signer.ShouldHashBody(request) {
|
||||
err = calculateHashOfBody(request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var signature string
|
||||
if signature, err = signer.computeSignature(request); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
signingHeaders := strings.Join(signer.getSigningHeaders(request), " ")
|
||||
|
||||
var keyID string
|
||||
if keyID, err = signer.KeyProvider.KeyID(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
authValue := fmt.Sprintf("Signature version=\"%s\",headers=\"%s\",keyId=\"%s\",algorithm=\"rsa-sha256\",signature=\"%s\"",
|
||||
signerVersion, signingHeaders, keyID, signature)
|
||||
|
||||
request.Header.Set(requestHeaderAuthorization, authValue)
|
||||
|
||||
return
|
||||
}
|
170
vendor/github.com/oracle/oci-go-sdk/common/log.go
generated
vendored
Normal file
170
vendor/github.com/oracle/oci-go-sdk/common/log.go
generated
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
//sdkLogger an interface for logging in the SDK
|
||||
type sdkLogger interface {
|
||||
//LogLevel returns the log level of sdkLogger
|
||||
LogLevel() int
|
||||
|
||||
//Log logs v with the provided format if the current log level is loglevel
|
||||
Log(logLevel int, format string, v ...interface{}) error
|
||||
}
|
||||
|
||||
//noLogging no logging messages
|
||||
const noLogging = 0
|
||||
|
||||
//infoLogging minimal logging messages
|
||||
const infoLogging = 1
|
||||
|
||||
//debugLogging some logging messages
|
||||
const debugLogging = 2
|
||||
|
||||
//verboseLogging all logging messages
|
||||
const verboseLogging = 3
|
||||
|
||||
//defaultSDKLogger the default implementation of the sdkLogger
|
||||
type defaultSDKLogger struct {
|
||||
currentLoggingLevel int
|
||||
verboseLogger *log.Logger
|
||||
debugLogger *log.Logger
|
||||
infoLogger *log.Logger
|
||||
nullLogger *log.Logger
|
||||
}
|
||||
|
||||
//defaultLogger is the defaultLogger in the SDK
|
||||
var defaultLogger sdkLogger
|
||||
var loggerLock sync.Mutex
|
||||
|
||||
//initializes the SDK defaultLogger as a defaultLogger
|
||||
func init() {
|
||||
l, _ := newSDKLogger()
|
||||
setSDKLogger(l)
|
||||
}
|
||||
|
||||
//setSDKLogger sets the logger used by the sdk
|
||||
func setSDKLogger(logger sdkLogger) {
|
||||
loggerLock.Lock()
|
||||
defaultLogger = logger
|
||||
loggerLock.Unlock()
|
||||
}
|
||||
|
||||
// newSDKLogger creates a defaultSDKLogger
|
||||
// Debug logging is turned on/off by the presence of the environment variable "OCI_GO_SDK_DEBUG"
|
||||
// The value of the "OCI_GO_SDK_DEBUG" environment variable controls the logging level.
|
||||
// "null" outputs no log messages
|
||||
// "i" or "info" outputs minimal log messages
|
||||
// "d" or "debug" outputs some logs messages
|
||||
// "v" or "verbose" outputs all logs messages, including body of requests
|
||||
func newSDKLogger() (defaultSDKLogger, error) {
|
||||
logger := defaultSDKLogger{}
|
||||
|
||||
logger.currentLoggingLevel = noLogging
|
||||
logger.verboseLogger = log.New(os.Stderr, "VERBOSE ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
|
||||
logger.debugLogger = log.New(os.Stderr, "DEBUG ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
|
||||
logger.infoLogger = log.New(os.Stderr, "INFO ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
|
||||
logger.nullLogger = log.New(ioutil.Discard, "", log.Ldate|log.Lmicroseconds|log.Lshortfile)
|
||||
|
||||
configured, isLogEnabled := os.LookupEnv("OCI_GO_SDK_DEBUG")
|
||||
|
||||
// If env variable not present turn logging of
|
||||
if !isLogEnabled {
|
||||
logger.currentLoggingLevel = noLogging
|
||||
} else {
|
||||
|
||||
switch strings.ToLower(configured) {
|
||||
case "null":
|
||||
logger.currentLoggingLevel = noLogging
|
||||
break
|
||||
case "i", "info":
|
||||
logger.currentLoggingLevel = infoLogging
|
||||
break
|
||||
case "d", "debug":
|
||||
logger.currentLoggingLevel = debugLogging
|
||||
break
|
||||
//1 here for backwards compatibility
|
||||
case "v", "verbose", "1":
|
||||
logger.currentLoggingLevel = verboseLogging
|
||||
break
|
||||
default:
|
||||
logger.currentLoggingLevel = infoLogging
|
||||
}
|
||||
logger.infoLogger.Println("logger level set to: ", logger.currentLoggingLevel)
|
||||
}
|
||||
|
||||
return logger, nil
|
||||
}
|
||||
|
||||
func (l defaultSDKLogger) getLoggerForLevel(logLevel int) *log.Logger {
|
||||
if logLevel > l.currentLoggingLevel {
|
||||
return l.nullLogger
|
||||
}
|
||||
|
||||
switch logLevel {
|
||||
case noLogging:
|
||||
return l.nullLogger
|
||||
case infoLogging:
|
||||
return l.infoLogger
|
||||
case debugLogging:
|
||||
return l.debugLogger
|
||||
case verboseLogging:
|
||||
return l.verboseLogger
|
||||
default:
|
||||
return l.nullLogger
|
||||
}
|
||||
}
|
||||
|
||||
//LogLevel returns the current debug level
|
||||
func (l defaultSDKLogger) LogLevel() int {
|
||||
return l.currentLoggingLevel
|
||||
}
|
||||
|
||||
func (l defaultSDKLogger) Log(logLevel int, format string, v ...interface{}) error {
|
||||
logger := l.getLoggerForLevel(logLevel)
|
||||
logger.Output(4, fmt.Sprintf(format, v...))
|
||||
return nil
|
||||
}
|
||||
|
||||
//Logln logs v appending a new line at the end
|
||||
//Deprecated
|
||||
func Logln(v ...interface{}) {
|
||||
defaultLogger.Log(infoLogging, "%v\n", v...)
|
||||
}
|
||||
|
||||
// Logf logs v with the provided format
|
||||
func Logf(format string, v ...interface{}) {
|
||||
defaultLogger.Log(infoLogging, format, v...)
|
||||
}
|
||||
|
||||
// Debugf logs v with the provided format if debug mode is set
|
||||
func Debugf(format string, v ...interface{}) {
|
||||
defaultLogger.Log(debugLogging, format, v...)
|
||||
}
|
||||
|
||||
// Debug logs v if debug mode is set
|
||||
func Debug(v ...interface{}) {
|
||||
m := fmt.Sprint(v...)
|
||||
defaultLogger.Log(debugLogging, "%s", m)
|
||||
}
|
||||
|
||||
// Debugln logs v appending a new line if debug mode is set
|
||||
func Debugln(v ...interface{}) {
|
||||
m := fmt.Sprint(v...)
|
||||
defaultLogger.Log(debugLogging, "%s\n", m)
|
||||
}
|
||||
|
||||
// IfDebug executes closure if debug is enabled
|
||||
func IfDebug(fn func()) {
|
||||
if defaultLogger.LogLevel() >= debugLogging {
|
||||
fn()
|
||||
}
|
||||
}
|
159
vendor/github.com/oracle/oci-go-sdk/common/retry.go
generated
vendored
Normal file
159
vendor/github.com/oracle/oci-go-sdk/common/retry.go
generated
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// UnlimitedNumAttemptsValue is the value for indicating unlimited attempts for reaching success
|
||||
UnlimitedNumAttemptsValue = uint(0)
|
||||
|
||||
// number of characters contained in the generated retry token
|
||||
generatedRetryTokenLength = 32
|
||||
)
|
||||
|
||||
// OCIRetryableRequest represents a request that can be reissued according to the specified policy.
|
||||
type OCIRetryableRequest interface {
|
||||
// Any retryable request must implement the OCIRequest interface
|
||||
OCIRequest
|
||||
|
||||
// Each operation specifies default retry behavior. By passing no arguments to this method, the default retry
|
||||
// behavior, as determined on a per-operation-basis, will be honored. Variadic retry policy option arguments
|
||||
// passed to this method will override the default behavior.
|
||||
RetryPolicy() *RetryPolicy
|
||||
}
|
||||
|
||||
// OCIOperationResponse represents the output of an OCIOperation, with additional context of error message
|
||||
// and operation attempt number.
|
||||
type OCIOperationResponse struct {
|
||||
// Response from OCI Operation
|
||||
Response OCIResponse
|
||||
|
||||
// Error from OCI Operation
|
||||
Error error
|
||||
|
||||
// Operation Attempt Number (one-based)
|
||||
AttemptNumber uint
|
||||
}
|
||||
|
||||
// NewOCIOperationResponse assembles an OCI Operation Response object.
|
||||
func NewOCIOperationResponse(response OCIResponse, err error, attempt uint) OCIOperationResponse {
|
||||
return OCIOperationResponse{
|
||||
Response: response,
|
||||
Error: err,
|
||||
AttemptNumber: attempt,
|
||||
}
|
||||
}
|
||||
|
||||
// RetryPolicy is the class that holds all relevant information for retrying operations.
|
||||
type RetryPolicy struct {
|
||||
// MaximumNumberAttempts is the maximum number of times to retry a request. Zero indicates an unlimited
|
||||
// number of attempts.
|
||||
MaximumNumberAttempts uint
|
||||
|
||||
// ShouldRetryOperation inspects the http response, error, and operation attempt number, and
|
||||
// - returns true if we should retry the operation
|
||||
// - returns false otherwise
|
||||
ShouldRetryOperation func(OCIOperationResponse) bool
|
||||
|
||||
// GetNextDuration computes the duration to pause between operation retries.
|
||||
NextDuration func(OCIOperationResponse) time.Duration
|
||||
}
|
||||
|
||||
// NoRetryPolicy is a helper method that assembles and returns a return policy that indicates an operation should
|
||||
// never be retried (the operation is performed exactly once).
|
||||
func NoRetryPolicy() RetryPolicy {
|
||||
dontRetryOperation := func(OCIOperationResponse) bool { return false }
|
||||
zeroNextDuration := func(OCIOperationResponse) time.Duration { return 0 * time.Second }
|
||||
return NewRetryPolicy(uint(1), dontRetryOperation, zeroNextDuration)
|
||||
}
|
||||
|
||||
// NewRetryPolicy is a helper method for assembling a Retry Policy object.
|
||||
func NewRetryPolicy(attempts uint, retryOperation func(OCIOperationResponse) bool, nextDuration func(OCIOperationResponse) time.Duration) RetryPolicy {
|
||||
return RetryPolicy{
|
||||
MaximumNumberAttempts: attempts,
|
||||
ShouldRetryOperation: retryOperation,
|
||||
NextDuration: nextDuration,
|
||||
}
|
||||
}
|
||||
|
||||
// shouldContinueIssuingRequests returns true if we should continue retrying a request, based on the current attempt
|
||||
// number and the maximum number of attempts specified, or false otherwise.
|
||||
func shouldContinueIssuingRequests(current, maximum uint) bool {
|
||||
return maximum == UnlimitedNumAttemptsValue || current <= maximum
|
||||
}
|
||||
|
||||
// RetryToken generates a retry token that must be included on any request passed to the Retry method.
|
||||
func RetryToken() string {
|
||||
alphanumericChars := []rune("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
retryToken := make([]rune, generatedRetryTokenLength)
|
||||
for i := range retryToken {
|
||||
retryToken[i] = alphanumericChars[rand.Intn(len(alphanumericChars))]
|
||||
}
|
||||
return string(retryToken)
|
||||
}
|
||||
|
||||
// Retry is a package-level operation that executes the retryable request using the specified operation and retry policy.
|
||||
func Retry(ctx context.Context, request OCIRetryableRequest, operation OCIOperation, policy RetryPolicy) (OCIResponse, error) {
|
||||
|
||||
type retrierResult struct {
|
||||
response OCIResponse
|
||||
err error
|
||||
}
|
||||
|
||||
var response OCIResponse
|
||||
var err error
|
||||
retrierChannel := make(chan retrierResult)
|
||||
|
||||
go func() {
|
||||
|
||||
// Deal with panics more graciously
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
stackBuffer := make([]byte, 1024)
|
||||
bytesWritten := runtime.Stack(stackBuffer, false)
|
||||
stack := string(stackBuffer[:bytesWritten])
|
||||
retrierChannel <- retrierResult{nil, fmt.Errorf("panicked while retrying operation. Panic was: %s\nStack: %s", r, stack)}
|
||||
}
|
||||
}()
|
||||
|
||||
// use a one-based counter because it's easier to think about operation retry in terms of attempt numbering
|
||||
for currentOperationAttempt := uint(1); shouldContinueIssuingRequests(currentOperationAttempt, policy.MaximumNumberAttempts); currentOperationAttempt++ {
|
||||
Debugln(fmt.Sprintf("operation attempt #%v", currentOperationAttempt))
|
||||
response, err = operation(ctx, request)
|
||||
operationResponse := NewOCIOperationResponse(response, err, currentOperationAttempt)
|
||||
|
||||
if !policy.ShouldRetryOperation(operationResponse) {
|
||||
// we should NOT retry operation based on response and/or error => return
|
||||
retrierChannel <- retrierResult{response, err}
|
||||
return
|
||||
}
|
||||
|
||||
duration := policy.NextDuration(operationResponse)
|
||||
//The following condition is kept for backwards compatibility reasons
|
||||
if deadline, ok := ctx.Deadline(); ok && time.Now().Add(duration).After(deadline) {
|
||||
// we want to retry the operation, but the policy is telling us to wait for a duration that exceeds
|
||||
// the specified overall deadline for the operation => instead of waiting for however long that
|
||||
// time period is and then aborting, abort now and save the cycles
|
||||
retrierChannel <- retrierResult{response, DeadlineExceededByBackoff}
|
||||
return
|
||||
}
|
||||
Debugln(fmt.Sprintf("waiting %v before retrying operation", duration))
|
||||
// sleep before retrying the operation
|
||||
<-time.After(duration)
|
||||
}
|
||||
|
||||
retrierChannel <- retrierResult{nil, fmt.Errorf("maximum number of attempts exceeded (%v)", policy.MaximumNumberAttempts)}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return response, ctx.Err()
|
||||
case result := <-retrierChannel:
|
||||
return result.response, result.err
|
||||
}
|
||||
}
|
36
vendor/github.com/oracle/oci-go-sdk/common/version.go
generated
vendored
Normal file
36
vendor/github.com/oracle/oci-go-sdk/common/version.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
// Code generated by go generate; DO NOT EDIT
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
major = "4"
|
||||
minor = "0"
|
||||
patch = "0"
|
||||
tag = ""
|
||||
)
|
||||
|
||||
var once sync.Once
|
||||
var version string
|
||||
|
||||
// Version returns semantic version of the sdk
|
||||
func Version() string {
|
||||
once.Do(func() {
|
||||
ver := fmt.Sprintf("%s.%s.%s", major, minor, patch)
|
||||
verBuilder := bytes.NewBufferString(ver)
|
||||
if tag != "" && tag != "-" {
|
||||
_, err := verBuilder.WriteString(tag)
|
||||
if err == nil {
|
||||
verBuilder = bytes.NewBufferString(ver)
|
||||
}
|
||||
}
|
||||
version = verBuilder.String()
|
||||
})
|
||||
return version
|
||||
}
|
42
vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_attachment_details.go
generated
vendored
Normal file
42
vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_attachment_details.go
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
// Code generated. DO NOT EDIT.
|
||||
|
||||
// DNS API
|
||||
//
|
||||
// API for the DNS service. Use this API to manage DNS zones, records, and other DNS resources.
|
||||
// For more information, see Overview of the DNS Service (https://docs.us-phoenix-1.oraclecloud.com/iaas/Content/DNS/Concepts/dnszonemanagement.htm).
|
||||
//
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"github.com/oracle/oci-go-sdk/common"
|
||||
)
|
||||
|
||||
// CreateSteeringPolicyAttachmentDetails The body for defining an attachment between a steering policy and a domain.
|
||||
// An attachment occludes all records at its domain that are of a covered rtype, constructing
|
||||
// DNS responses from its steering policy rather than from those domain records.
|
||||
// The attachment will cover every rtype that matches the rtype of an answer in its policy, and
|
||||
// will cover all address rtypes (e.g., A and AAAA) if the policy includes at least one CNAME
|
||||
// answer.
|
||||
// A domain can have at most one attachment covering any given rtype.
|
||||
type CreateSteeringPolicyAttachmentDetails struct {
|
||||
|
||||
// The OCID of the attached steering policy.
|
||||
SteeringPolicyId *string `mandatory:"true" json:"steeringPolicyId"`
|
||||
|
||||
// The OCID of the attached zone.
|
||||
ZoneId *string `mandatory:"true" json:"zoneId"`
|
||||
|
||||
// The attached domain within the attached zone.
|
||||
DomainName *string `mandatory:"true" json:"domainName"`
|
||||
|
||||
// A user-friendly name for the steering policy attachment.
|
||||
// Does not have to be unique, and it's changeable.
|
||||
// Avoid entering confidential information.
|
||||
DisplayName *string `mandatory:"false" json:"displayName"`
|
||||
}
|
||||
|
||||
func (m CreateSteeringPolicyAttachmentDetails) String() string {
|
||||
return common.PointerString(m)
|
||||
}
|
75
vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_attachment_request_response.go
generated
vendored
Normal file
75
vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_attachment_request_response.go
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
// Code generated. DO NOT EDIT.
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"github.com/oracle/oci-go-sdk/common"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// CreateSteeringPolicyAttachmentRequest wrapper for the CreateSteeringPolicyAttachment operation
|
||||
type CreateSteeringPolicyAttachmentRequest struct {
|
||||
|
||||
// Details for creating a new steering policy attachment.
|
||||
CreateSteeringPolicyAttachmentDetails `contributesTo:"body"`
|
||||
|
||||
// A token that uniquely identifies a request so it can be retried in case
|
||||
// of a timeout or server error without risk of executing that same action
|
||||
// again. Retry tokens expire after 24 hours, but can be invalidated before
|
||||
// then due to conflicting operations (for example, if a resource has been
|
||||
// deleted and purged from the system, then a retry of the original creation
|
||||
// request may be rejected).
|
||||
OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"`
|
||||
|
||||
// Unique Oracle-assigned identifier for the request.
|
||||
// If you need to contact Oracle about a particular request, please provide the request ID.
|
||||
OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"`
|
||||
|
||||
// Metadata about the request. This information will not be transmitted to the service, but
|
||||
// represents information that the SDK will consume to drive retry behavior.
|
||||
RequestMetadata common.RequestMetadata
|
||||
}
|
||||
|
||||
func (request CreateSteeringPolicyAttachmentRequest) String() string {
|
||||
return common.PointerString(request)
|
||||
}
|
||||
|
||||
// HTTPRequest implements the OCIRequest interface
|
||||
func (request CreateSteeringPolicyAttachmentRequest) HTTPRequest(method, path string) (http.Request, error) {
|
||||
return common.MakeDefaultHTTPRequestWithTaggedStruct(method, path, request)
|
||||
}
|
||||
|
||||
// RetryPolicy implements the OCIRetryableRequest interface. This retrieves the specified retry policy.
|
||||
func (request CreateSteeringPolicyAttachmentRequest) RetryPolicy() *common.RetryPolicy {
|
||||
return request.RequestMetadata.RetryPolicy
|
||||
}
|
||||
|
||||
// CreateSteeringPolicyAttachmentResponse wrapper for the CreateSteeringPolicyAttachment operation
|
||||
type CreateSteeringPolicyAttachmentResponse struct {
|
||||
|
||||
// The underlying http response
|
||||
RawResponse *http.Response
|
||||
|
||||
// The SteeringPolicyAttachment instance
|
||||
SteeringPolicyAttachment `presentIn:"body"`
|
||||
|
||||
// Unique Oracle-assigned identifier for the request. If you need to
|
||||
// contact Oracle about a particular request, please provide the request
|
||||
// ID.
|
||||
OpcRequestId *string `presentIn:"header" name:"opc-request-id"`
|
||||
|
||||
// The current version of the resource, ending with a
|
||||
// representation-specific suffix. This value may be used in If-Match
|
||||
// and If-None-Match headers for later requests of the same resource.
|
||||
ETag *string `presentIn:"header" name:"etag"`
|
||||
}
|
||||
|
||||
func (response CreateSteeringPolicyAttachmentResponse) String() string {
|
||||
return common.PointerString(response)
|
||||
}
|
||||
|
||||
// HTTPResponse implements the OCIResponse interface
|
||||
func (response CreateSteeringPolicyAttachmentResponse) HTTPResponse() *http.Response {
|
||||
return response.RawResponse
|
||||
}
|
177
vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_details.go
generated
vendored
Normal file
177
vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_details.go
generated
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
// Code generated. DO NOT EDIT.
|
||||
|
||||
// DNS API
|
||||
//
|
||||
// API for the DNS service. Use this API to manage DNS zones, records, and other DNS resources.
|
||||
// For more information, see Overview of the DNS Service (https://docs.us-phoenix-1.oraclecloud.com/iaas/Content/DNS/Concepts/dnszonemanagement.htm).
|
||||
//
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/oracle/oci-go-sdk/common"
|
||||
)
|
||||
|
||||
// CreateSteeringPolicyDetails The body for defining a new steering policy.
|
||||
// *Warning:* Oracle recommends that you avoid using any confidential information when you supply string values using the API.
|
||||
type CreateSteeringPolicyDetails struct {
|
||||
|
||||
// The OCID of the compartment containing the steering policy.
|
||||
CompartmentId *string `mandatory:"true" json:"compartmentId"`
|
||||
|
||||
// A user-friendly name for the steering policy.
|
||||
// Does not have to be unique, and it's changeable.
|
||||
// Avoid entering confidential information.
|
||||
DisplayName *string `mandatory:"true" json:"displayName"`
|
||||
|
||||
// The common pattern (or lack thereof) to which the steering policy adheres. This
|
||||
// value restricts the possible configurations of rules, but thereby supports
|
||||
// specifically tailored interfaces. Values other than "CUSTOM" require the rules to
|
||||
// begin with an unconditional FILTER that keeps answers contingent upon
|
||||
// `answer.isDisabled != true`, followed
|
||||
// _if and only if the policy references a health check monitor_ by an unconditional
|
||||
// HEALTH rule, and require the last rule to be an unconditional LIMIT.
|
||||
// What must precede the LIMIT rule is determined by the template value:
|
||||
// - FAILOVER requires exactly an unconditional PRIORITY rule that ranks answers by pool.
|
||||
// Each answer pool must have a unique priority value assigned to it. Answer data must
|
||||
// be defined in the `defaultAnswerData` property for the rule and the `cases` property
|
||||
// must not be defined.
|
||||
// - LOAD_BALANCE requires exactly an unconditional WEIGHTED rule that shuffles answers
|
||||
// by name. Answer data must be defined in the `defaultAnswerData` property for the
|
||||
// rule and the `cases` property must not be defined.
|
||||
// - ROUTE_BY_GEO requires exactly one PRIORITY rule that ranks answers by pool using the
|
||||
// geographical location of the client as a condition. Within that rule you may only
|
||||
// use `query.client.geoKey` in the `caseCondition` expressions for defining the cases.
|
||||
// For each case in the PRIORITY rule each answer pool must have a unique priority
|
||||
// value assigned to it. Answer data can only be defined within cases and
|
||||
// `defaultAnswerData` cannot be used in the PRIORITY rule.
|
||||
// - ROUTE_BY_ASN requires exactly one PRIORITY rule that ranks answers by pool using the
|
||||
// ASN of the client as a condition. Within that rule you may only use
|
||||
// `query.client.asn` in the `caseCondition` expressions for defining the cases.
|
||||
// For each case in the PRIORITY rule each answer pool must have a unique priority
|
||||
// value assigned to it. Answer data can only be defined within cases and
|
||||
// `defaultAnswerData` cannot be used in the PRIORITY rule.
|
||||
// - ROUTE_BY_IP requires exactly one PRIORITY rule that ranks answers by pool using the
|
||||
// IP subnet of the client as a condition. Within that rule you may only use
|
||||
// `query.client.address` in the `caseCondition` expressions for defining the cases.
|
||||
// For each case in the PRIORITY rule each answer pool must have a unique priority
|
||||
// value assigned to it. Answer data can only be defined within cases and
|
||||
// `defaultAnswerData` cannot be used in the PRIORITY rule.
|
||||
// - CUSTOM allows an arbitrary configuration of rules.
|
||||
// For an existing steering policy, the template value may be changed to any of the
|
||||
// supported options but the resulting policy must conform to the requirements for the
|
||||
// new template type or else a Bad Request error will be returned.
|
||||
Template CreateSteeringPolicyDetailsTemplateEnum `mandatory:"true" json:"template"`
|
||||
|
||||
// The Time To Live for responses from the steering policy, in seconds.
|
||||
// If not specified during creation, a value of 30 seconds will be used.
|
||||
Ttl *int `mandatory:"false" json:"ttl"`
|
||||
|
||||
// The OCID of the health check monitor providing health data about the answers of the
|
||||
// steering policy.
|
||||
// A steering policy answer with `rdata` matching a monitored endpoint will use the health
|
||||
// data of that endpoint.
|
||||
// A steering policy answer with `rdata` not matching any monitored endpoint will be assumed
|
||||
// healthy.
|
||||
HealthCheckMonitorId *string `mandatory:"false" json:"healthCheckMonitorId"`
|
||||
|
||||
// Simple key-value pair that is applied without any predefined name, type, or scope.
|
||||
// For more information, see Resource Tags (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/resourcetags.htm).
|
||||
// Example: `{"bar-key": "value"}`
|
||||
FreeformTags map[string]string `mandatory:"false" json:"freeformTags"`
|
||||
|
||||
// Usage of predefined tag keys. These predefined keys are scoped to a namespace.
|
||||
// Example: `{"foo-namespace": {"bar-key": "value"}}`
|
||||
DefinedTags map[string]map[string]interface{} `mandatory:"false" json:"definedTags"`
|
||||
|
||||
// The set of all answers that can potentially issue from the steering policy.
|
||||
Answers []SteeringPolicyAnswer `mandatory:"false" json:"answers"`
|
||||
|
||||
// The pipeline of rules that will be processed in sequence to reduce the pool of answers
|
||||
// to a response for any given request.
|
||||
// The first rule receives a shuffled list of all answers, and every other rule receives
|
||||
// the list of answers emitted by the one preceding it. The last rule populates the
|
||||
// response.
|
||||
Rules []SteeringPolicyRule `mandatory:"false" json:"rules"`
|
||||
}
|
||||
|
||||
func (m CreateSteeringPolicyDetails) String() string {
|
||||
return common.PointerString(m)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals from json
|
||||
func (m *CreateSteeringPolicyDetails) UnmarshalJSON(data []byte) (e error) {
|
||||
model := struct {
|
||||
Ttl *int `json:"ttl"`
|
||||
HealthCheckMonitorId *string `json:"healthCheckMonitorId"`
|
||||
FreeformTags map[string]string `json:"freeformTags"`
|
||||
DefinedTags map[string]map[string]interface{} `json:"definedTags"`
|
||||
Answers []SteeringPolicyAnswer `json:"answers"`
|
||||
Rules []steeringpolicyrule `json:"rules"`
|
||||
CompartmentId *string `json:"compartmentId"`
|
||||
DisplayName *string `json:"displayName"`
|
||||
Template CreateSteeringPolicyDetailsTemplateEnum `json:"template"`
|
||||
}{}
|
||||
|
||||
e = json.Unmarshal(data, &model)
|
||||
if e != nil {
|
||||
return
|
||||
}
|
||||
m.Ttl = model.Ttl
|
||||
m.HealthCheckMonitorId = model.HealthCheckMonitorId
|
||||
m.FreeformTags = model.FreeformTags
|
||||
m.DefinedTags = model.DefinedTags
|
||||
m.Answers = make([]SteeringPolicyAnswer, len(model.Answers))
|
||||
for i, n := range model.Answers {
|
||||
m.Answers[i] = n
|
||||
}
|
||||
m.Rules = make([]SteeringPolicyRule, len(model.Rules))
|
||||
for i, n := range model.Rules {
|
||||
nn, err := n.UnmarshalPolymorphicJSON(n.JsonData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if nn != nil {
|
||||
m.Rules[i] = nn.(SteeringPolicyRule)
|
||||
} else {
|
||||
m.Rules[i] = nil
|
||||
}
|
||||
}
|
||||
m.CompartmentId = model.CompartmentId
|
||||
m.DisplayName = model.DisplayName
|
||||
m.Template = model.Template
|
||||
return
|
||||
}
|
||||
|
||||
// CreateSteeringPolicyDetailsTemplateEnum Enum with underlying type: string
|
||||
type CreateSteeringPolicyDetailsTemplateEnum string
|
||||
|
||||
// Set of constants representing the allowable values for CreateSteeringPolicyDetailsTemplateEnum
|
||||
const (
|
||||
CreateSteeringPolicyDetailsTemplateFailover CreateSteeringPolicyDetailsTemplateEnum = "FAILOVER"
|
||||
CreateSteeringPolicyDetailsTemplateLoadBalance CreateSteeringPolicyDetailsTemplateEnum = "LOAD_BALANCE"
|
||||
CreateSteeringPolicyDetailsTemplateRouteByGeo CreateSteeringPolicyDetailsTemplateEnum = "ROUTE_BY_GEO"
|
||||
CreateSteeringPolicyDetailsTemplateRouteByAsn CreateSteeringPolicyDetailsTemplateEnum = "ROUTE_BY_ASN"
|
||||
CreateSteeringPolicyDetailsTemplateRouteByIp CreateSteeringPolicyDetailsTemplateEnum = "ROUTE_BY_IP"
|
||||
CreateSteeringPolicyDetailsTemplateCustom CreateSteeringPolicyDetailsTemplateEnum = "CUSTOM"
|
||||
)
|
||||
|
||||
var mappingCreateSteeringPolicyDetailsTemplate = map[string]CreateSteeringPolicyDetailsTemplateEnum{
|
||||
"FAILOVER": CreateSteeringPolicyDetailsTemplateFailover,
|
||||
"LOAD_BALANCE": CreateSteeringPolicyDetailsTemplateLoadBalance,
|
||||
"ROUTE_BY_GEO": CreateSteeringPolicyDetailsTemplateRouteByGeo,
|
||||
"ROUTE_BY_ASN": CreateSteeringPolicyDetailsTemplateRouteByAsn,
|
||||
"ROUTE_BY_IP": CreateSteeringPolicyDetailsTemplateRouteByIp,
|
||||
"CUSTOM": CreateSteeringPolicyDetailsTemplateCustom,
|
||||
}
|
||||
|
||||
// GetCreateSteeringPolicyDetailsTemplateEnumValues Enumerates the set of values for CreateSteeringPolicyDetailsTemplateEnum
|
||||
func GetCreateSteeringPolicyDetailsTemplateEnumValues() []CreateSteeringPolicyDetailsTemplateEnum {
|
||||
values := make([]CreateSteeringPolicyDetailsTemplateEnum, 0)
|
||||
for _, v := range mappingCreateSteeringPolicyDetailsTemplate {
|
||||
values = append(values, v)
|
||||
}
|
||||
return values
|
||||
}
|
75
vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_request_response.go
generated
vendored
Normal file
75
vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_request_response.go
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
// Code generated. DO NOT EDIT.
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"github.com/oracle/oci-go-sdk/common"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// CreateSteeringPolicyRequest wrapper for the CreateSteeringPolicy operation
|
||||
type CreateSteeringPolicyRequest struct {
|
||||
|
||||
// Details for creating a new steering policy.
|
||||
CreateSteeringPolicyDetails `contributesTo:"body"`
|
||||
|
||||
// A token that uniquely identifies a request so it can be retried in case
|
||||
// of a timeout or server error without risk of executing that same action
|
||||
// again. Retry tokens expire after 24 hours, but can be invalidated before
|
||||
// then due to conflicting operations (for example, if a resource has been
|
||||
// deleted and purged from the system, then a retry of the original creation
|
||||
// request may be rejected).
|
||||
OpcRetryToken *string `mandatory:"false" contributesTo:"header" name:"opc-retry-token"`
|
||||
|
||||
// Unique Oracle-assigned identifier for the request.
|
||||
// If you need to contact Oracle about a particular request, please provide the request ID.
|
||||
OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"`
|
||||
|
||||
// Metadata about the request. This information will not be transmitted to the service, but
|
||||
// represents information that the SDK will consume to drive retry behavior.
|
||||
RequestMetadata common.RequestMetadata
|
||||
}
|
||||
|
||||
func (request CreateSteeringPolicyRequest) String() string {
|
||||
return common.PointerString(request)
|
||||
}
|
||||
|
||||
// HTTPRequest implements the OCIRequest interface
|
||||
func (request CreateSteeringPolicyRequest) HTTPRequest(method, path string) (http.Request, error) {
|
||||
return common.MakeDefaultHTTPRequestWithTaggedStruct(method, path, request)
|
||||
}
|
||||
|
||||
// RetryPolicy implements the OCIRetryableRequest interface. This retrieves the specified retry policy.
|
||||
func (request CreateSteeringPolicyRequest) RetryPolicy() *common.RetryPolicy {
|
||||
return request.RequestMetadata.RetryPolicy
|
||||
}
|
||||
|
||||
// CreateSteeringPolicyResponse wrapper for the CreateSteeringPolicy operation
|
||||
type CreateSteeringPolicyResponse struct {
|
||||
|
||||
// The underlying http response
|
||||
RawResponse *http.Response
|
||||
|
||||
// The SteeringPolicy instance
|
||||
SteeringPolicy `presentIn:"body"`
|
||||
|
||||
// Unique Oracle-assigned identifier for the request. If you need to
|
||||
// contact Oracle about a particular request, please provide the request
|
||||
// ID.
|
||||
OpcRequestId *string `presentIn:"header" name:"opc-request-id"`
|
||||
|
||||
// The current version of the resource, ending with a
|
||||
// representation-specific suffix. This value may be used in If-Match
|
||||
// and If-None-Match headers for later requests of the same resource.
|
||||
ETag *string `presentIn:"header" name:"etag"`
|
||||
}
|
||||
|
||||
func (response CreateSteeringPolicyResponse) String() string {
|
||||
return common.PointerString(response)
|
||||
}
|
||||
|
||||
// HTTPResponse implements the OCIResponse interface
|
||||
func (response CreateSteeringPolicyResponse) HTTPResponse() *http.Response {
|
||||
return response.RawResponse
|
||||
}
|
68
vendor/github.com/oracle/oci-go-sdk/dns/create_zone_details.go
generated
vendored
Normal file
68
vendor/github.com/oracle/oci-go-sdk/dns/create_zone_details.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
// Code generated. DO NOT EDIT.
|
||||
|
||||
// DNS API
|
||||
//
|
||||
// API for the DNS service. Use this API to manage DNS zones, records, and other DNS resources.
|
||||
// For more information, see Overview of the DNS Service (https://docs.us-phoenix-1.oraclecloud.com/iaas/Content/DNS/Concepts/dnszonemanagement.htm).
|
||||
//
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"github.com/oracle/oci-go-sdk/common"
|
||||
)
|
||||
|
||||
// CreateZoneDetails The body for defining a new zone.
|
||||
// *Warning:* Oracle recommends that you avoid using any confidential information when you supply string values using the API.
|
||||
type CreateZoneDetails struct {
|
||||
|
||||
// The name of the zone.
|
||||
Name *string `mandatory:"true" json:"name"`
|
||||
|
||||
// The type of the zone. Must be either `PRIMARY` or `SECONDARY`.
|
||||
ZoneType CreateZoneDetailsZoneTypeEnum `mandatory:"true" json:"zoneType"`
|
||||
|
||||
// The OCID of the compartment containing the zone.
|
||||
CompartmentId *string `mandatory:"true" json:"compartmentId"`
|
||||
|
||||
// Simple key-value pair that is applied without any predefined name, type, or scope.
|
||||
// For more information, see Resource Tags (https://docs.us-phoenix-1.oraclecloud.com/Content/General/Concepts/resourcetags.htm).
|
||||
// Example: `{"bar-key": "value"}`
|
||||
FreeformTags map[string]string `mandatory:"false" json:"freeformTags"`
|
||||
|
||||
// Usage of predefined tag keys. These predefined keys are scoped to a namespace.
|
||||
// Example: `{"foo-namespace": {"bar-key": "value"}}`
|
||||
DefinedTags map[string]map[string]interface{} `mandatory:"false" json:"definedTags"`
|
||||
|
||||
// External master servers for the zone. `externalMasters` becomes a
|
||||
// required parameter when the `zoneType` value is `SECONDARY`.
|
||||
ExternalMasters []ExternalMaster `mandatory:"false" json:"externalMasters"`
|
||||
}
|
||||
|
||||
func (m CreateZoneDetails) String() string {
|
||||
return common.PointerString(m)
|
||||
}
|
||||
|
||||
// CreateZoneDetailsZoneTypeEnum Enum with underlying type: string
|
||||
type CreateZoneDetailsZoneTypeEnum string
|
||||
|
||||
// Set of constants representing the allowable values for CreateZoneDetailsZoneTypeEnum
|
||||
const (
|
||||
CreateZoneDetailsZoneTypePrimary CreateZoneDetailsZoneTypeEnum = "PRIMARY"
|
||||
CreateZoneDetailsZoneTypeSecondary CreateZoneDetailsZoneTypeEnum = "SECONDARY"
|
||||
)
|
||||
|
||||
var mappingCreateZoneDetailsZoneType = map[string]CreateZoneDetailsZoneTypeEnum{
|
||||
"PRIMARY": CreateZoneDetailsZoneTypePrimary,
|
||||
"SECONDARY": CreateZoneDetailsZoneTypeSecondary,
|
||||
}
|
||||
|
||||
// GetCreateZoneDetailsZoneTypeEnumValues Enumerates the set of values for CreateZoneDetailsZoneTypeEnum
|
||||
func GetCreateZoneDetailsZoneTypeEnumValues() []CreateZoneDetailsZoneTypeEnum {
|
||||
values := make([]CreateZoneDetailsZoneTypeEnum, 0)
|
||||
for _, v := range mappingCreateZoneDetailsZoneType {
|
||||
values = append(values, v)
|
||||
}
|
||||
return values
|
||||
}
|
69
vendor/github.com/oracle/oci-go-sdk/dns/create_zone_request_response.go
generated
vendored
Normal file
69
vendor/github.com/oracle/oci-go-sdk/dns/create_zone_request_response.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
// Code generated. DO NOT EDIT.
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"github.com/oracle/oci-go-sdk/common"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// CreateZoneRequest wrapper for the CreateZone operation
|
||||
type CreateZoneRequest struct {
|
||||
|
||||
// Details for creating a new zone.
|
||||
CreateZoneDetails `contributesTo:"body"`
|
||||
|
||||
// The OCID of the compartment the resource belongs to.
|
||||
CompartmentId *string `mandatory:"false" contributesTo:"query" name:"compartmentId"`
|
||||
|
||||
// Unique Oracle-assigned identifier for the request.
|
||||
// If you need to contact Oracle about a particular request, please provide the request ID.
|
||||
OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"`
|
||||
|
||||
// Metadata about the request. This information will not be transmitted to the service, but
|
||||
// represents information that the SDK will consume to drive retry behavior.
|
||||
RequestMetadata common.RequestMetadata
|
||||
}
|
||||
|
||||
func (request CreateZoneRequest) String() string {
|
||||
return common.PointerString(request)
|
||||
}
|
||||
|
||||
// HTTPRequest implements the OCIRequest interface
|
||||
func (request CreateZoneRequest) HTTPRequest(method, path string) (http.Request, error) {
|
||||
return common.MakeDefaultHTTPRequestWithTaggedStruct(method, path, request)
|
||||
}
|
||||
|
||||
// RetryPolicy implements the OCIRetryableRequest interface. This retrieves the specified retry policy.
|
||||
func (request CreateZoneRequest) RetryPolicy() *common.RetryPolicy {
|
||||
return request.RequestMetadata.RetryPolicy
|
||||
}
|
||||
|
||||
// CreateZoneResponse wrapper for the CreateZone operation
|
||||
type CreateZoneResponse struct {
|
||||
|
||||
// The underlying http response
|
||||
RawResponse *http.Response
|
||||
|
||||
// The Zone instance
|
||||
Zone `presentIn:"body"`
|
||||
|
||||
// Unique Oracle-assigned identifier for the request. If you need to
|
||||
// contact Oracle about a particular request, please provide the request ID.
|
||||
OpcRequestId *string `presentIn:"header" name:"opc-request-id"`
|
||||
|
||||
// The current version of the zone, ending with a
|
||||
// representation-specific suffix. This value may be used in If-Match
|
||||
// and If-None-Match headers for later requests of the same resource.
|
||||
ETag *string `presentIn:"header" name:"etag"`
|
||||
}
|
||||
|
||||
func (response CreateZoneResponse) String() string {
|
||||
return common.PointerString(response)
|
||||
}
|
||||
|
||||
// HTTPResponse implements the OCIResponse interface
|
||||
func (response CreateZoneResponse) HTTPResponse() *http.Response {
|
||||
return response.RawResponse
|
||||
}
|
79
vendor/github.com/oracle/oci-go-sdk/dns/delete_domain_records_request_response.go
generated
vendored
Normal file
79
vendor/github.com/oracle/oci-go-sdk/dns/delete_domain_records_request_response.go
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
// Code generated. DO NOT EDIT.
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"github.com/oracle/oci-go-sdk/common"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// DeleteDomainRecordsRequest wrapper for the DeleteDomainRecords operation
|
||||
type DeleteDomainRecordsRequest struct {
|
||||
|
||||
// The name or OCID of the target zone.
|
||||
ZoneNameOrId *string `mandatory:"true" contributesTo:"path" name:"zoneNameOrId"`
|
||||
|
||||
// The target fully-qualified domain name (FQDN) within the target zone.
|
||||
Domain *string `mandatory:"true" contributesTo:"path" name:"domain"`
|
||||
|
||||
// The `If-Match` header field makes the request method conditional on the
|
||||
// existence of at least one current representation of the target resource,
|
||||
// when the field-value is `*`, or having a current representation of the
|
||||
// target resource that has an entity-tag matching a member of the list of
|
||||
// entity-tags provided in the field-value.
|
||||
IfMatch *string `mandatory:"false" contributesTo:"header" name:"If-Match"`
|
||||
|
||||
// The `If-Unmodified-Since` header field makes the request method
|
||||
// conditional on the selected representation's last modification date being
|
||||
// earlier than or equal to the date provided in the field-value. This
|
||||
// field accomplishes the same purpose as If-Match for cases where the user
|
||||
// agent does not have an entity-tag for the representation.
|
||||
IfUnmodifiedSince *string `mandatory:"false" contributesTo:"header" name:"If-Unmodified-Since"`
|
||||
|
||||
// The OCID of the compartment the resource belongs to.
|
||||
CompartmentId *string `mandatory:"false" contributesTo:"query" name:"compartmentId"`
|
||||
|
||||
// Unique Oracle-assigned identifier for the request.
|
||||
// If you need to contact Oracle about a particular request, please provide the request ID.
|
||||
OpcRequestId *string `mandatory:"false" contributesTo:"header" name:"opc-request-id"`
|
||||
|
||||
// Metadata about the request. This information will not be transmitted to the service, but
|
||||
// represents information that the SDK will consume to drive retry behavior.
|
||||
RequestMetadata common.RequestMetadata
|
||||
}
|
||||
|
||||
func (request DeleteDomainRecordsRequest) String() string {
|
||||
return common.PointerString(request)
|
||||
}
|
||||
|
||||
// HTTPRequest implements the OCIRequest interface
|
||||
func (request DeleteDomainRecordsRequest) HTTPRequest(method, path string) (http.Request, error) {
|
||||
return common.MakeDefaultHTTPRequestWithTaggedStruct(method, path, request)
|
||||
}
|
||||
|
||||
// RetryPolicy implements the OCIRetryableRequest interface. This retrieves the specified retry policy.
|
||||
func (request DeleteDomainRecordsRequest) RetryPolicy() *common.RetryPolicy {
|
||||
return request.RequestMetadata.RetryPolicy
|
||||
}
|
||||
|
||||
// DeleteDomainRecordsResponse wrapper for the DeleteDomainRecords operation
|
||||
type DeleteDomainRecordsResponse struct {
|
||||
|
||||
// The underlying http response
|
||||
RawResponse *http.Response
|
||||
|
||||
// Unique Oracle-assigned identifier for the request. If you need
|
||||
// to contact Oracle about a particular request, please provide
|
||||
// the request ID.
|
||||
OpcRequestId *string `presentIn:"header" name:"opc-request-id"`
|
||||
}
|
||||
|
||||
func (response DeleteDomainRecordsResponse) String() string {
|
||||
return common.PointerString(response)
|
||||
}
|
||||
|
||||
// HTTPResponse implements the OCIResponse interface
|
||||
func (response DeleteDomainRecordsResponse) HTTPResponse() *http.Response {
|
||||
return response.RawResponse
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue