forked from SW/traefik
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
266f5d18a8 | ||
|
|
305af43fb9 | ||
|
|
30545808d9 | ||
|
|
358f125a58 | ||
|
|
57ae9a80d5 | ||
|
|
e32c021f16 | ||
|
|
0db2a9aadd | ||
|
|
4f4dab3ca5 | ||
|
|
eaee39e534 | ||
|
|
d85eb0495c | ||
|
|
8aa618775d | ||
|
|
f6b7e333be | ||
|
|
108d9dbb3f | ||
|
|
2a1fa32950 | ||
|
|
ee7aa77833 | ||
|
|
fcc4cab614 | ||
|
|
1206cd52fc | ||
|
|
5cdba752a4 | ||
|
|
b48ea1e173 | ||
|
|
373040f552 |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1 +1 @@
|
||||
# vendor/github.com/xenolf/lego/providers/dns/cloudxns/cloudxns.go eol=crlf
|
||||
# vendor/github.com/go-acme/lego/providers/dns/cloudxns/cloudxns.go eol=crlf
|
||||
|
||||
18
.gitignore
vendored
18
.gitignore
vendored
@@ -1,15 +1,17 @@
|
||||
/dist
|
||||
/autogen/genstatic/gen.go
|
||||
.idea/
|
||||
.intellij/
|
||||
*.iml
|
||||
/traefik
|
||||
/traefik.toml
|
||||
/static/
|
||||
/webui/.tmp/
|
||||
.vscode/
|
||||
.DS_Store
|
||||
/static/
|
||||
/autogen/genstatic/gen.go
|
||||
/webui/.tmp/
|
||||
/examples/acme/acme.json
|
||||
/site/
|
||||
/docs/site/
|
||||
/traefik.toml
|
||||
/dist
|
||||
/traefik
|
||||
*.log
|
||||
*.exe
|
||||
.DS_Store
|
||||
/examples/acme/acme.json
|
||||
cover.out
|
||||
|
||||
10
.travis.yml
10
.travis.yml
@@ -30,9 +30,8 @@ before_deploy:
|
||||
make -j${N_MAKE_JOBS} crossbinary-parallel;
|
||||
tar cfz dist/traefik-${VERSION}.src.tar.gz --exclude-vcs --exclude dist .;
|
||||
fi;
|
||||
curl -sI https://github.com/containous/structor/releases/latest | grep -Fi Location | tr -d '\r' | sed "s/tag/download/g" | awk -F " " '{ print $2 "/structor_linux-amd64"}' | wget --output-document=$GOPATH/bin/structor -i -;
|
||||
chmod +x $GOPATH/bin/structor;
|
||||
structor -o containous -r traefik --dockerfile-url="https://raw.githubusercontent.com/containous/traefik/master/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/containous/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/containous/structor/master/requirements-override.txt" --exp-branch=master --debug;
|
||||
curl -sfL https://raw.githubusercontent.com/containous/structor/master/godownloader.sh | bash -s -- -b "${GOPATH}/bin" v1.7.0
|
||||
structor -o containous -r traefik --dockerfile-url="https://raw.githubusercontent.com/containous/traefik/v1.7/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/containous/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/containous/structor/master/requirements-override.txt" --exp-branch=master --force-edit-url --debug;
|
||||
fi
|
||||
deploy:
|
||||
- provider: releases
|
||||
@@ -49,11 +48,6 @@ deploy:
|
||||
on:
|
||||
repo: containous/traefik
|
||||
tags: true
|
||||
- provider: script
|
||||
script: sh script/deploy-docker.sh
|
||||
skip_cleanup: true
|
||||
on:
|
||||
repo: containous/traefik
|
||||
- provider: pages
|
||||
edge: false
|
||||
github_token: ${GITHUB_TOKEN}
|
||||
|
||||
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,5 +1,22 @@
|
||||
# Change Log
|
||||
|
||||
## [v1.7.10](https://github.com/containous/traefik/tree/v1.7.10) (2019-03-28)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.9...v1.7.10)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** fix: update lego. ([#4670](https://github.com/containous/traefik/pull/4670) by [ldez](https://github.com/ldez))
|
||||
- **[acme]** Migrate to go-acme/lego. ([#4577](https://github.com/containous/traefik/pull/4577) by [ldez](https://github.com/ldez))
|
||||
- **[authentication,middleware]** Reorder Auth and TLSClientHeaders middleware ([#4557](https://github.com/containous/traefik/pull/4557) by [tomberek](https://github.com/tomberek))
|
||||
- **[k8s/ingress]** Support external name service on global default backend ([#4564](https://github.com/containous/traefik/pull/4564) by [kippandrew](https://github.com/kippandrew))
|
||||
- **[k8s/ingress]** Loop through service ports for global backend ([#4486](https://github.com/containous/traefik/pull/4486) by [dtomcej](https://github.com/dtomcej))
|
||||
- **[k8s]** Add entrypoints prefix in kubernetes frontend/backend id ([#4679](https://github.com/containous/traefik/pull/4679) by [juliens](https://github.com/juliens))
|
||||
- **[websocket]** Exclude websocket connections from Average Response Time ([#4313](https://github.com/containous/traefik/pull/4313) by [siyu6974](https://github.com/siyu6974))
|
||||
- **[middleware]** Added support for configuring trace headers for DataDog tracing ([#4516](https://github.com/containous/traefik/pull/4516) by [aantono](https://github.com/aantono))
|
||||
|
||||
**Documentation:**
|
||||
- **[acme]** Add _FILE Environment Variable Documentation ([#4643](https://github.com/containous/traefik/pull/4643) by [dargmuesli](https://github.com/dargmuesli))
|
||||
- **[docker]** Add TraefikEE as security workaround ([#4606](https://github.com/containous/traefik/pull/4606) by [emilevauge](https://github.com/emilevauge))
|
||||
|
||||
## [v1.7.9](https://github.com/containous/traefik/tree/v1.7.9) (2019-02-11)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v1.7.8...v1.7.9)
|
||||
|
||||
@@ -1124,7 +1141,7 @@
|
||||
- **[acme,tls]** Rename TLSConfigurations to TLS. ([#2744](https://github.com/containous/traefik/pull/2744) by [ldez](https://github.com/ldez))
|
||||
- **[acme,provider,docker,tls]** Make the TLS certificates management dynamic. ([#2233](https://github.com/containous/traefik/pull/2233) by [nmengin](https://github.com/nmengin))
|
||||
- **[acme]** Add Let's Encrypt HTTP Challenge ([#2701](https://github.com/containous/traefik/pull/2701) by [Juliens](https://github.com/Juliens))
|
||||
- **[acme]** Update github.com/xenolf/lego to 0.4.1 ([#2304](https://github.com/containous/traefik/pull/2304) by [oldmantaiter](https://github.com/oldmantaiter))
|
||||
- **[acme]** Update github.com/go-acme/lego to 0.4.1 ([#2304](https://github.com/containous/traefik/pull/2304) by [oldmantaiter](https://github.com/oldmantaiter))
|
||||
- **[api,healthcheck,metrics,provider,webui]** Split Web into API/Dashboard, ping, metric and Rest Provider ([#2335](https://github.com/containous/traefik/pull/2335) by [Juliens](https://github.com/Juliens))
|
||||
- **[authentication]** Pass through certain forward auth negative response headers ([#2127](https://github.com/containous/traefik/pull/2127) by [wheresmysocks](https://github.com/wheresmysocks))
|
||||
- **[cluster,consul,file]** Add file to storeconfig ([#2419](https://github.com/containous/traefik/pull/2419) by [emilevauge](https://github.com/emilevauge))
|
||||
@@ -1403,7 +1420,7 @@
|
||||
|
||||
**Enhancements:**
|
||||
- **[acme,provider,docker,tls]** Make the TLS certificates management dynamic. ([#2233](https://github.com/containous/traefik/pull/2233) by [nmengin](https://github.com/nmengin))
|
||||
- **[acme]** Update github.com/xenolf/lego to 0.4.1 ([#2304](https://github.com/containous/traefik/pull/2304) by [oldmantaiter](https://github.com/oldmantaiter))
|
||||
- **[acme]** Update github.com/go-acme/lego to 0.4.1 ([#2304](https://github.com/containous/traefik/pull/2304) by [oldmantaiter](https://github.com/oldmantaiter))
|
||||
- **[api,healthcheck,metrics,provider,webui]** Split Web into API/Dashboard, ping, metric and Rest Provider ([#2335](https://github.com/containous/traefik/pull/2335) by [Juliens](https://github.com/Juliens))
|
||||
- **[authentication]** Pass through certain forward auth negative response headers ([#2127](https://github.com/containous/traefik/pull/2127) by [wheresmysocks](https://github.com/wheresmysocks))
|
||||
- **[cluster,consul,file]** Add file to storeconfig ([#2419](https://github.com/containous/traefik/pull/2419) by [emilevauge](https://github.com/emilevauge))
|
||||
|
||||
@@ -87,7 +87,7 @@ If you happen to update the provider templates (in `/templates`), you need to ru
|
||||
|
||||
[dep](https://github.com/golang/dep) is not required for building; however, it is necessary to modify dependencies (i.e., add, update, or remove third-party packages)
|
||||
|
||||
You need to use [dep](https://github.com/golang/dep) >= 0.4.1 and < 0.5.0.
|
||||
You need to use [dep](https://github.com/golang/dep) >= 0.5.0.
|
||||
|
||||
If you want to add a dependency, use `dep ensure -add` to have [dep](https://github.com/golang/dep) put it into the vendor folder and update the dep manifest/lock files (`Gopkg.toml` and `Gopkg.lock`, respectively).
|
||||
|
||||
|
||||
2287
Gopkg.lock
generated
2287
Gopkg.lock
generated
File diff suppressed because it is too large
Load Diff
28
Gopkg.toml
28
Gopkg.toml
@@ -45,6 +45,11 @@
|
||||
name = "github.com/abbot/go-http-auth"
|
||||
source = "github.com/containous/go-http-auth"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/thoas/stats"
|
||||
# related to https://github.com/thoas/stats/pull/32
|
||||
revision = "4975baf6a358ed3ddaa42133996e1959f96c9300"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/armon/go-proxyproto"
|
||||
@@ -54,8 +59,8 @@
|
||||
version = "1.13.11"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/cenk/backoff"
|
||||
version = "v2.1.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/containous/flaeg"
|
||||
@@ -71,7 +76,7 @@
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/containous/traefik-extra-service-fabric"
|
||||
version = "1.4.0"
|
||||
version = "v1.5.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/coreos/go-systemd"
|
||||
@@ -117,8 +122,8 @@
|
||||
version = "1.3.7"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/jjcollinge/servicefabric"
|
||||
revision = "8eebe170fa1ba25d3dfb928b3f86a7313b13b9fe"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
@@ -128,18 +133,6 @@
|
||||
name = "github.com/mesosphere/mesos-dns"
|
||||
source = "https://github.com/containous/mesos-dns.git"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/copystructure"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/hashstructure"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/mapstructure"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/opentracing/opentracing-go"
|
||||
version = "1.0.2"
|
||||
@@ -186,9 +179,8 @@
|
||||
name = "github.com/vulcand/oxy"
|
||||
|
||||
[[constraint]]
|
||||
# branch = "master"
|
||||
name = "github.com/xenolf/lego"
|
||||
version = "2.0.1"
|
||||
name = "github.com/go-acme/lego"
|
||||
version = "2.4.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "google.golang.org/grpc"
|
||||
|
||||
@@ -113,13 +113,13 @@ If you need commercial support, please contact [Containo.us](https://containo.us
|
||||
|
||||
## Download
|
||||
|
||||
- Grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml):
|
||||
- Grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/v1.7/traefik.sample.toml):
|
||||
|
||||
```shell
|
||||
./traefik --configFile=traefik.toml
|
||||
```
|
||||
|
||||
- Or use the official tiny Docker image and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml):
|
||||
- Or use the official tiny Docker image and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/v1.7/traefik.sample.toml):
|
||||
|
||||
```shell
|
||||
docker run -d -p 8080:8080 -p 80:80 -v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik
|
||||
|
||||
@@ -17,8 +17,8 @@ import (
|
||||
"github.com/containous/traefik/log"
|
||||
acmeprovider "github.com/containous/traefik/provider/acme"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/xenolf/lego/certcrypto"
|
||||
"github.com/xenolf/lego/registration"
|
||||
"github.com/go-acme/lego/certcrypto"
|
||||
"github.com/go-acme/lego/registration"
|
||||
)
|
||||
|
||||
// Account is used to store lets encrypt registration info
|
||||
|
||||
18
acme/acme.go
18
acme/acme.go
@@ -27,19 +27,19 @@ import (
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/containous/traefik/version"
|
||||
"github.com/eapache/channels"
|
||||
"github.com/go-acme/lego/certificate"
|
||||
"github.com/go-acme/lego/challenge"
|
||||
"github.com/go-acme/lego/challenge/dns01"
|
||||
"github.com/go-acme/lego/challenge/http01"
|
||||
"github.com/go-acme/lego/lego"
|
||||
legolog "github.com/go-acme/lego/log"
|
||||
"github.com/go-acme/lego/providers/dns"
|
||||
"github.com/go-acme/lego/registration"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/xenolf/lego/certificate"
|
||||
"github.com/xenolf/lego/challenge"
|
||||
"github.com/xenolf/lego/challenge/dns01"
|
||||
"github.com/xenolf/lego/challenge/http01"
|
||||
"github.com/xenolf/lego/lego"
|
||||
legolog "github.com/xenolf/lego/log"
|
||||
"github.com/xenolf/lego/providers/dns"
|
||||
"github.com/xenolf/lego/registration"
|
||||
)
|
||||
|
||||
var (
|
||||
// OSCPMustStaple enables OSCP stapling as from https://github.com/xenolf/lego/issues/270
|
||||
// OSCPMustStaple enables OSCP stapling as from https://github.com/go-acme/lego/issues/270
|
||||
OSCPMustStaple = false
|
||||
)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/containous/traefik/cluster"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/safe"
|
||||
"github.com/xenolf/lego/challenge"
|
||||
"github.com/go-acme/lego/challenge"
|
||||
)
|
||||
|
||||
var _ challenge.ProviderTimeout = (*challengeHTTPProvider)(nil)
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
"github.com/containous/traefik/cluster"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/safe"
|
||||
"github.com/xenolf/lego/challenge"
|
||||
"github.com/xenolf/lego/challenge/tlsalpn01"
|
||||
"github.com/go-acme/lego/challenge"
|
||||
"github.com/go-acme/lego/challenge/tlsalpn01"
|
||||
)
|
||||
|
||||
var _ challenge.ProviderTimeout = (*challengeTLSProvider)(nil)
|
||||
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"github.com/containous/traefik/safe"
|
||||
traefiktls "github.com/containous/traefik/tls"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/elazarl/go-bindata-assetfs"
|
||||
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||
"github.com/thoas/stats"
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/containous/mux"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/elazarl/go-bindata-assetfs"
|
||||
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||
)
|
||||
|
||||
// DashboardHandler expose dashboard routes
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/containous/traefik/safe"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/containous/traefik/version"
|
||||
"github.com/elazarl/go-bindata-assetfs"
|
||||
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||
thoas_stats "github.com/thoas/stats"
|
||||
"github.com/unrolled/render"
|
||||
)
|
||||
|
||||
@@ -10,7 +10,7 @@ RUN go get golang.org/x/lint/golint \
|
||||
|
||||
# Which docker version to test on
|
||||
ARG DOCKER_VERSION=17.03.2
|
||||
ARG DEP_VERSION=0.4.1
|
||||
ARG DEP_VERSION=0.5.1
|
||||
|
||||
# Download go-bindata binary to bin folder in $GOPATH
|
||||
RUN mkdir -p /usr/local/bin \
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/containous/traefik/job"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/safe"
|
||||
"github.com/satori/go.uuid"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// Metadata stores Object plus metadata
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/traefik-extra-service-fabric"
|
||||
servicefabric "github.com/containous/traefik-extra-service-fabric"
|
||||
"github.com/containous/traefik/api"
|
||||
"github.com/containous/traefik/configuration"
|
||||
"github.com/containous/traefik/middlewares/accesslog"
|
||||
|
||||
@@ -34,7 +34,7 @@ import (
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/containous/traefik/version"
|
||||
"github.com/coreos/go-systemd/daemon"
|
||||
"github.com/elazarl/go-bindata-assetfs"
|
||||
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||
"github.com/ogier/pflag"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vulcand/oxy/roundrobin"
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/traefik-extra-service-fabric"
|
||||
servicefabric "github.com/containous/traefik-extra-service-fabric"
|
||||
"github.com/containous/traefik/acme"
|
||||
"github.com/containous/traefik/api"
|
||||
"github.com/containous/traefik/log"
|
||||
@@ -33,9 +33,9 @@ import (
|
||||
"github.com/containous/traefik/provider/zk"
|
||||
"github.com/containous/traefik/tls"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/go-acme/lego/challenge/dns01"
|
||||
"github.com/pkg/errors"
|
||||
jaegercli "github.com/uber/jaeger-client-go"
|
||||
"github.com/xenolf/lego/challenge/dns01"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -746,7 +746,7 @@ Once a day (the first call begins 10 minutes after the start of Traefik), we col
|
||||
|
||||
### Show me the code !
|
||||
|
||||
If you want to dig into more details, here is the source code of the collecting system: [collector.go](https://github.com/containous/traefik/blob/master/collector/collector.go)
|
||||
If you want to dig into more details, here is the source code of the collecting system: [collector.go](https://github.com/containous/traefik/blob/v1.7/collector/collector.go)
|
||||
|
||||
By default we anonymize all configuration fields, except fields tagged with `export=true`.
|
||||
|
||||
|
||||
@@ -273,63 +273,68 @@ Useful if internal networks block external DNS queries.
|
||||
|
||||
Here is a list of supported `provider`s, that can automate the DNS verification, along with the required environment variables and their [wildcard & root domain support](/configuration/acme/#wildcard-domains) for each.
|
||||
Do not hesitate to complete it.
|
||||
Every lego environment variable can be overridden by their respective `_FILE` counterpart, which should have a filepath to a file that contains the secret as its value.
|
||||
For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used to provide a Cloudflare API email address as a Docker secret named `traefik_cf-api-email`.
|
||||
|
||||
| Provider Name | Provider Code | Environment Variables | Wildcard & Root Domain Support |
|
||||
|-------------------------------------------------------------|----------------|-------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|
|
||||
| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | Not tested yet |
|
||||
| [Alibaba Cloud](https://www.vultr.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | Not tested yet |
|
||||
| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | Not tested yet |
|
||||
| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | Not tested yet |
|
||||
| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | Not tested yet |
|
||||
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` - The `Global API Key` needs to be used, not the `Origin CA Key` | YES |
|
||||
| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | Not tested yet |
|
||||
| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | YES |
|
||||
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | YES |
|
||||
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | YES |
|
||||
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | Not tested yet |
|
||||
| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | Not tested yet |
|
||||
| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | YES |
|
||||
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | YES |
|
||||
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | Not tested yet |
|
||||
| External Program | `exec` | `EXEC_PATH` | YES |
|
||||
| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | YES |
|
||||
| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | YES |
|
||||
| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | Not tested yet |
|
||||
| [Gandi v5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | YES |
|
||||
| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | Not tested yet |
|
||||
| [GoDaddy](https://godaddy.com/domains) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | Not tested yet |
|
||||
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials (2) (3), [`GCE_SERVICE_ACCOUNT_FILE`] | YES |
|
||||
| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | Not tested yet |
|
||||
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` (1) | YES |
|
||||
| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | Not tested yet |
|
||||
| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | YES |
|
||||
| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | Not tested yet |
|
||||
| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` | Not tested yet |
|
||||
| [Linode v4](https://www.linode.com) | `linodev4` | `LINODE_TOKEN` | Not tested yet |
|
||||
| manual | - | none, but you need to run Traefik interactively, turn on `acmeLogging` to see instructions and press <kbd>Enter</kbd>. | YES |
|
||||
| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | YES |
|
||||
| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | YES |
|
||||
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | Not tested yet |
|
||||
| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | Not tested yet |
|
||||
| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | Not tested yet |
|
||||
| [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | Not tested yet |
|
||||
| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | Not tested yet |
|
||||
| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | YES |
|
||||
| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | YES |
|
||||
| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | Not tested yet |
|
||||
| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | Not tested yet |
|
||||
| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | Not tested yet |
|
||||
| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | YES |
|
||||
| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | Not tested yet |
|
||||
| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | YES |
|
||||
| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | Not tested yet |
|
||||
| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | YES |
|
||||
| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | Not tested yet |
|
||||
| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | YES |
|
||||
| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | Not tested yet |
|
||||
| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | YES |
|
||||
| Provider Name | Provider Code | Environment Variables | Wildcard & Root Domain Support |
|
||||
|-------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|
|
||||
| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | Not tested yet |
|
||||
| [Alibaba Cloud](https://www.vultr.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | Not tested yet |
|
||||
| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | Not tested yet |
|
||||
| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | Not tested yet |
|
||||
| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | Not tested yet |
|
||||
| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | YES |
|
||||
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` - The `Global API Key` needs to be used, not the `Origin CA Key` | YES |
|
||||
| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | Not tested yet |
|
||||
| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | YES |
|
||||
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | YES |
|
||||
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | YES |
|
||||
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | Not tested yet |
|
||||
| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | Not tested yet |
|
||||
| [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | YES |
|
||||
| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | YES |
|
||||
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | YES |
|
||||
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | Not tested yet |
|
||||
| External Program | `exec` | `EXEC_PATH` | YES |
|
||||
| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | YES |
|
||||
| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | YES |
|
||||
| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | Not tested yet |
|
||||
| [Gandi v5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | YES |
|
||||
| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | Not tested yet |
|
||||
| [GoDaddy](https://godaddy.com/domains) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | Not tested yet |
|
||||
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials (2) (3), [`GCE_SERVICE_ACCOUNT_FILE`] | YES |
|
||||
| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | Not tested yet |
|
||||
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` (1) | YES |
|
||||
| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | Not tested yet |
|
||||
| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | YES |
|
||||
| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | Not tested yet |
|
||||
| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` | Not tested yet |
|
||||
| [Linode v4](https://www.linode.com) | `linodev4` | `LINODE_TOKEN` | Not tested yet |
|
||||
| manual | - | none, but you need to run Traefik interactively, turn on `acmeLogging` to see instructions and press <kbd>Enter</kbd>. | YES |
|
||||
| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | YES |
|
||||
| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | YES |
|
||||
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | Not tested yet |
|
||||
| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | Not tested yet |
|
||||
| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | Not tested yet |
|
||||
| [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | Not tested yet |
|
||||
| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | Not tested yet |
|
||||
| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | YES |
|
||||
| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | YES |
|
||||
| [Oracle Cloud](https://cloud.oracle.com/home) | `oraclecloud` | `OCI_COMPARTMENT_OCID`, `OCI_PRIVKEY_FILE`, `OCI_PRIVKEY_PASS`, `OCI_PUBKEY_FINGERPRINT`, `OCI_REGION`, `OCI_TENANCY_OCID`, `OCI_USER_OCID` | YES |
|
||||
| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | Not tested yet |
|
||||
| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | Not tested yet |
|
||||
| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | Not tested yet |
|
||||
| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | YES |
|
||||
| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | Not tested yet |
|
||||
| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | YES |
|
||||
| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | Not tested yet |
|
||||
| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | YES |
|
||||
| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | Not tested yet |
|
||||
| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | YES |
|
||||
| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | Not tested yet |
|
||||
| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | YES |
|
||||
|
||||
- (1): more information about the HTTP message format can be found [here](https://github.com/xenolf/lego/blob/master/providers/dns/httpreq/readme.md)
|
||||
- (1): more information about the HTTP message format can be found [here](https://go-acme.github.io/lego/dns/httpreq/)
|
||||
- (2): https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application
|
||||
- (3): https://github.com/golang/oauth2/blob/36a7019397c4c86cf59eeab3bc0d188bac444277/google/default.go#L61-L76
|
||||
|
||||
@@ -393,7 +398,7 @@ Due to ACME limitation it is not possible to define wildcards in SANs (alternati
|
||||
Most likely the root domain should receive a certificate too, so it needs to be specified as SAN and 2 `DNS-01` challenges are executed.
|
||||
In this case the generated DNS TXT record for both domains is the same.
|
||||
Even though this behaviour is [DNS RFC](https://community.letsencrypt.org/t/wildcard-issuance-two-txt-records-for-the-same-name/54528/2) compliant, it can lead to problems as all DNS providers keep DNS records cached for a certain time (TTL) and this TTL can be superior to the challenge timeout making the `DNS-01` challenge fail.
|
||||
The Traefik ACME client library [LEGO](https://github.com/xenolf/lego) supports some but not all DNS providers to work around this issue.
|
||||
The Traefik ACME client library [LEGO](https://github.com/go-acme/lego) supports some but not all DNS providers to work around this issue.
|
||||
The [`provider` table](/configuration/acme/#provider) indicates if they allow generating certificates for a wildcard domain and its root domain.
|
||||
|
||||
### `onDemand` (Deprecated)
|
||||
|
||||
@@ -213,9 +213,13 @@ More information about Docker's security:
|
||||
- [A thread on Stack Overflow about sharing the `/var/run/docker.sock` file](https://news.ycombinator.com/item?id=17983623)
|
||||
- [To Dind or not to DinD](https://blog.loof.fr/2018/01/to-dind-or-not-do-dind.html)
|
||||
|
||||
### Security Compensation
|
||||
### Workarounds
|
||||
|
||||
The main security compensation is to expose the Docker socket over TCP, instead of the default Unix socket file.
|
||||
!!! note "Improved Security"
|
||||
|
||||
[TraefikEE](https://containo.us/traefikee) solves this problem by separating the control plane (connected to Docker) and the data plane (handling the requests).
|
||||
|
||||
Another possible workaround is to expose the Docker socket over TCP, instead of the default Unix socket file.
|
||||
It allows different implementation levels of the [AAA (Authentication, Authorization, Accounting) concepts](https://en.wikipedia.org/wiki/AAA_(computer_security)), depending on your security assessment:
|
||||
|
||||
- Authentication with Client Certificates as described in [the "Protect the Docker daemon socket" page of Docker's documentation](https://docs.docker.com/engine/security/https/)
|
||||
|
||||
@@ -66,7 +66,7 @@ _(But if you'd rather configure some of your routes manually, Traefik supports t
|
||||
|
||||
In this quickstart, we'll use [Docker compose](https://docs.docker.com/compose) to create our demo infrastructure.
|
||||
|
||||
To save some time, you can clone [Traefik's repository](https://github.com/containous/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/containous/traefik/tree/master/examples/quickstart/) directory.
|
||||
To save some time, you can clone [Traefik's repository](https://github.com/containous/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/containous/traefik/tree/v1.7/examples/quickstart/) directory.
|
||||
|
||||
### 1 — Launch Traefik — Tell It to Listen to Docker
|
||||
|
||||
@@ -190,7 +190,7 @@ You will learn fundamental Traefik features and see some demos with Kubernetes.
|
||||
|
||||
### The Official Binary File
|
||||
|
||||
You can grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page and just run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml):
|
||||
You can grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page and just run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/v1.7/traefik.sample.toml):
|
||||
|
||||
```shell
|
||||
./traefik -c traefik.toml
|
||||
|
||||
@@ -4,7 +4,7 @@ This guide explains how to use Traefik as an Ingress controller for a Kubernetes
|
||||
|
||||
If you are not familiar with Ingresses in Kubernetes you might want to read the [Kubernetes user guide](https://kubernetes.io/docs/concepts/services-networking/ingress/)
|
||||
|
||||
The config files used in this guide can be found in the [examples directory](https://github.com/containous/traefik/tree/master/examples/k8s)
|
||||
The config files used in this guide can be found in the [examples directory](https://github.com/containous/traefik/tree/v1.7/examples/k8s)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -68,10 +68,10 @@ subjects:
|
||||
namespace: kube-system
|
||||
```
|
||||
|
||||
[examples/k8s/traefik-rbac.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-rbac.yaml)
|
||||
[examples/k8s/traefik-rbac.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/traefik-rbac.yaml)
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-rbac.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-rbac.yaml
|
||||
```
|
||||
|
||||
For namespaced restrictions, one RoleBinding is required per watched namespace along with a corresponding configuration of Traefik's `kubernetes.namespaces` parameter.
|
||||
@@ -148,7 +148,7 @@ spec:
|
||||
type: NodePort
|
||||
```
|
||||
|
||||
[examples/k8s/traefik-deployment.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-deployment.yaml)
|
||||
[examples/k8s/traefik-deployment.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/traefik-deployment.yaml)
|
||||
|
||||
!!! note
|
||||
The Service will expose two NodePorts which allow access to the ingress and the web interface.
|
||||
@@ -216,7 +216,7 @@ spec:
|
||||
name: admin
|
||||
```
|
||||
|
||||
[examples/k8s/traefik-ds.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-ds.yaml)
|
||||
[examples/k8s/traefik-ds.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/traefik-ds.yaml)
|
||||
|
||||
!!! note
|
||||
This will create a Daemonset that uses privileged ports 80/8080 on the host. This may not work on all providers, but illustrates the static (non-NodePort) hostPort binding. The `traefik-ingress-service` can still be used inside the cluster to access the DaemonSet pods.
|
||||
@@ -224,11 +224,11 @@ spec:
|
||||
To deploy Traefik to your cluster start by submitting one of the YAML files to the cluster with `kubectl`:
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-deployment.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-deployment.yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-ds.yaml
|
||||
```
|
||||
|
||||
There are some significant differences between using Deployments and DaemonSets:
|
||||
@@ -352,10 +352,10 @@ spec:
|
||||
servicePort: web
|
||||
```
|
||||
|
||||
[examples/k8s/ui.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/ui.yaml)
|
||||
[examples/k8s/ui.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/ui.yaml)
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/ui.yaml
|
||||
```
|
||||
|
||||
Now lets setup an entry in our `/etc/hosts` file to route `traefik-ui.minikube` to our cluster.
|
||||
@@ -581,10 +581,10 @@ spec:
|
||||
- containerPort: 80
|
||||
```
|
||||
|
||||
[examples/k8s/cheese-deployments.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-deployments.yaml)
|
||||
[examples/k8s/cheese-deployments.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/cheese-deployments.yaml)
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-deployments.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/cheese-deployments.yaml
|
||||
```
|
||||
|
||||
Next we need to setup a Service for each of the cheese pods.
|
||||
@@ -636,10 +636,10 @@ spec:
|
||||
!!! note
|
||||
We also set a [circuit breaker expression](/basics/#backends) for one of the backends by setting the `traefik.backend.circuitbreaker` annotation on the service.
|
||||
|
||||
[examples/k8s/cheese-services.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-services.yaml)
|
||||
[examples/k8s/cheese-services.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/cheese-services.yaml)
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-services.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/cheese-services.yaml
|
||||
```
|
||||
|
||||
Now we can submit an ingress for the cheese websites.
|
||||
@@ -676,13 +676,13 @@ spec:
|
||||
servicePort: http
|
||||
```
|
||||
|
||||
[examples/k8s/cheese-ingress.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-ingress.yaml)
|
||||
[examples/k8s/cheese-ingress.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/cheese-ingress.yaml)
|
||||
|
||||
!!! note
|
||||
We list each hostname, and add a backend service.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-ingress.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/cheese-ingress.yaml
|
||||
```
|
||||
|
||||
Now visit the [Traefik dashboard](http://traefik-ui.minikube/) and you should see a frontend for each host.
|
||||
@@ -731,13 +731,13 @@ spec:
|
||||
servicePort: http
|
||||
```
|
||||
|
||||
[examples/k8s/cheeses-ingress.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheeses-ingress.yaml)
|
||||
[examples/k8s/cheeses-ingress.yaml](https://github.com/containous/traefik/tree/v1.7/examples/k8s/cheeses-ingress.yaml)
|
||||
|
||||
!!! note
|
||||
We are configuring Traefik to strip the prefix from the url path with the `traefik.frontend.rule.type` annotation so that we can use the containers from the previous example without modification.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheeses-ingress.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/cheeses-ingress.yaml
|
||||
```
|
||||
|
||||
```shell
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
In this quickstart, we'll use [Docker compose](https://docs.docker.com/compose) to create our demo infrastructure.
|
||||
|
||||
To save some time, you can clone [Traefik's repository](https://github.com/containous/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/containous/traefik/tree/master/examples/quickstart/) directory.
|
||||
To save some time, you can clone [Traefik's repository](https://github.com/containous/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/containous/traefik/tree/v1.7/examples/quickstart/) directory.
|
||||
|
||||
### 1 — Launch Traefik — Tell It to Listen to Docker
|
||||
|
||||
|
||||
42
exp.Dockerfile
Normal file
42
exp.Dockerfile
Normal file
@@ -0,0 +1,42 @@
|
||||
# WEBUI
|
||||
FROM node:8.15.0 as webui
|
||||
|
||||
ENV WEBUI_DIR /src/webui
|
||||
RUN mkdir -p $WEBUI_DIR
|
||||
|
||||
COPY ./webui/ $WEBUI_DIR/
|
||||
|
||||
WORKDIR $WEBUI_DIR
|
||||
RUN yarn install
|
||||
|
||||
RUN npm run build
|
||||
|
||||
# BUILD
|
||||
FROM golang:1.11-alpine as gobuild
|
||||
|
||||
RUN apk --update upgrade \
|
||||
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
RUN mkdir -p /usr/local/bin \
|
||||
&& curl -fsSL -o /usr/local/bin/go-bindata https://github.com/containous/go-bindata/releases/download/v1.0.0/go-bindata \
|
||||
&& chmod +x /usr/local/bin/go-bindata
|
||||
|
||||
WORKDIR /go/src/github.com/containous/traefik
|
||||
COPY . /go/src/github.com/containous/traefik
|
||||
|
||||
RUN rm -rf /go/src/github.com/containous/traefik/static/
|
||||
COPY --from=webui /src/static/ /go/src/github.com/containous/traefik/static/
|
||||
|
||||
RUN ./script/make.sh generate binary
|
||||
|
||||
## IMAGE
|
||||
FROM scratch
|
||||
|
||||
COPY script/ca-certificates.crt /etc/ssl/certs/
|
||||
COPY --from=gobuild /go/src/github.com/containous/traefik/dist/traefik /
|
||||
|
||||
EXPOSE 80
|
||||
VOLUME ["/tmp"]
|
||||
|
||||
ENTRYPOINT ["/traefik"]
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/abronan/valkeyrie"
|
||||
"github.com/abronan/valkeyrie/store"
|
||||
"github.com/abronan/valkeyrie/store/etcd/v3"
|
||||
etcdv3 "github.com/abronan/valkeyrie/store/etcd/v3"
|
||||
"github.com/containous/traefik/integration/try"
|
||||
"github.com/go-check/check"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
pebble:
|
||||
image: letsencrypt/pebble:2018-11-02
|
||||
image: letsencrypt/pebble:v2.0.1
|
||||
command: pebble --dnsserver ${DOCKER_HOST_IP}:5053
|
||||
ports:
|
||||
- 14000:14000
|
||||
|
||||
@@ -44,8 +44,9 @@ func TestLogRotation(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Error setting up temporary directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
fileName := tempDir + "traefik.log"
|
||||
fileName := filepath.Join(tempDir, "traefik.log")
|
||||
rotatedFileName := fileName + ".rotated"
|
||||
|
||||
config := &types.AccessLog{FilePath: fileName, Format: CommonFormat}
|
||||
@@ -587,6 +588,7 @@ func captureStdout(t *testing.T) (out *os.File, restoreStdout func()) {
|
||||
|
||||
restoreStdout = func() {
|
||||
os.Stdout = original
|
||||
os.RemoveAll(file.Name())
|
||||
}
|
||||
|
||||
return file, restoreStdout
|
||||
|
||||
@@ -15,10 +15,14 @@ const Name = "datadog"
|
||||
|
||||
// Config provides configuration settings for a datadog tracer
|
||||
type Config struct {
|
||||
LocalAgentHostPort string `description:"Set datadog-agent's host:port that the reporter will used. Defaults to localhost:8126" export:"false"`
|
||||
GlobalTag string `description:"Key:Value tag to be set on all the spans." export:"true"`
|
||||
Debug bool `description:"Enable DataDog debug." export:"true"`
|
||||
PrioritySampling bool `description:"Enable priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled."`
|
||||
LocalAgentHostPort string `description:"Set datadog-agent's host:port that the reporter will used. Defaults to localhost:8126" export:"false"`
|
||||
GlobalTag string `description:"Key:Value tag to be set on all the spans." export:"true"`
|
||||
Debug bool `description:"Enable DataDog debug." export:"true"`
|
||||
PrioritySampling bool `description:"Enable priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled."`
|
||||
TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID." export:"true"`
|
||||
ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." export:"true"`
|
||||
SamplingPriorityHeaderName string `description:"Specifies the header name that will be used to store the sampling priority." export:"true"`
|
||||
BagagePrefixHeaderName string `description:"specifies the header name prefix that will be used to store baggage items in a map." export:"true"`
|
||||
}
|
||||
|
||||
// Setup sets up the tracer
|
||||
@@ -35,6 +39,12 @@ func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error
|
||||
datadog.WithServiceName(serviceName),
|
||||
datadog.WithGlobalTag(tag[0], value),
|
||||
datadog.WithDebugMode(c.Debug),
|
||||
datadog.WithPropagator(datadog.NewPropagator(&datadog.PropagatorConfig{
|
||||
TraceHeader: c.TraceIDHeaderName,
|
||||
ParentHeader: c.ParentIDHeaderName,
|
||||
PriorityHeader: c.SamplingPriorityHeaderName,
|
||||
BaggagePrefix: c.BagagePrefixHeaderName,
|
||||
})),
|
||||
}
|
||||
if c.PrioritySampling {
|
||||
opts = append(opts, datadog.WithPrioritySampling())
|
||||
|
||||
@@ -6,6 +6,7 @@ dev_addr: 0.0.0.0:8000
|
||||
|
||||
repo_name: 'GitHub'
|
||||
repo_url: 'https://github.com/containous/traefik'
|
||||
edit_uri: 'edit/v1.7/docs/'
|
||||
|
||||
docs_dir: 'docs'
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"crypto/x509"
|
||||
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/xenolf/lego/certcrypto"
|
||||
"github.com/xenolf/lego/registration"
|
||||
"github.com/go-acme/lego/certcrypto"
|
||||
"github.com/go-acme/lego/registration"
|
||||
)
|
||||
|
||||
// Account is used to store lets encrypt registration info
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"github.com/containous/mux"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/safe"
|
||||
"github.com/xenolf/lego/challenge"
|
||||
"github.com/xenolf/lego/challenge/http01"
|
||||
"github.com/go-acme/lego/challenge"
|
||||
"github.com/go-acme/lego/challenge/http01"
|
||||
)
|
||||
|
||||
var _ challenge.ProviderTimeout = (*challengeHTTP)(nil)
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/xenolf/lego/challenge"
|
||||
"github.com/xenolf/lego/challenge/tlsalpn01"
|
||||
"github.com/go-acme/lego/challenge"
|
||||
"github.com/go-acme/lego/challenge/tlsalpn01"
|
||||
)
|
||||
|
||||
var _ challenge.Provider = (*challengeTLSALPN)(nil)
|
||||
|
||||
@@ -20,19 +20,19 @@ import (
|
||||
traefiktls "github.com/containous/traefik/tls"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/containous/traefik/version"
|
||||
"github.com/go-acme/lego/certificate"
|
||||
"github.com/go-acme/lego/challenge"
|
||||
"github.com/go-acme/lego/challenge/dns01"
|
||||
"github.com/go-acme/lego/lego"
|
||||
legolog "github.com/go-acme/lego/log"
|
||||
"github.com/go-acme/lego/providers/dns"
|
||||
"github.com/go-acme/lego/registration"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/xenolf/lego/certificate"
|
||||
"github.com/xenolf/lego/challenge"
|
||||
"github.com/xenolf/lego/challenge/dns01"
|
||||
"github.com/xenolf/lego/lego"
|
||||
legolog "github.com/xenolf/lego/log"
|
||||
"github.com/xenolf/lego/providers/dns"
|
||||
"github.com/xenolf/lego/registration"
|
||||
)
|
||||
|
||||
var (
|
||||
// OSCPMustStaple enables OSCP stapling as from https://github.com/xenolf/lego/issues/270
|
||||
// OSCPMustStaple enables OSCP stapling as from https://github.com/go-acme/lego/issues/270
|
||||
OSCPMustStaple = false
|
||||
)
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"github.com/containous/traefik/safe"
|
||||
traefiktls "github.com/containous/traefik/tls"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/go-acme/lego/certcrypto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/xenolf/lego/certcrypto"
|
||||
)
|
||||
|
||||
func TestGetUncheckedCertificates(t *testing.T) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/abronan/valkeyrie/store"
|
||||
"github.com/abronan/valkeyrie/store/etcd/v2"
|
||||
"github.com/abronan/valkeyrie/store/etcd/v3"
|
||||
etcdv3 "github.com/abronan/valkeyrie/store/etcd/v3"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/provider"
|
||||
"github.com/containous/traefik/provider/kv"
|
||||
|
||||
@@ -330,13 +330,13 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) (*Provider,
|
||||
}
|
||||
|
||||
return provider, func() {
|
||||
os.Remove(tempDir)
|
||||
os.RemoveAll(tempDir)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTLSContent(t *testing.T) {
|
||||
tempDir := createTempDir(t, "testdir")
|
||||
defer os.Remove(tempDir)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
fileTLS := createRandomFile(t, tempDir, "CONTENT")
|
||||
fileConfig := createRandomFile(t, tempDir, `
|
||||
|
||||
@@ -245,6 +245,11 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||
baseName = pa.Backend.ServiceName
|
||||
}
|
||||
|
||||
entryPoints := getSliceStringValue(i.Annotations, annotationKubernetesFrontendEntryPoints)
|
||||
if len(entryPoints) > 0 {
|
||||
baseName = strings.Join(entryPoints, "-") + "_" + baseName
|
||||
}
|
||||
|
||||
if priority > 0 {
|
||||
baseName = strconv.Itoa(priority) + "-" + baseName
|
||||
}
|
||||
@@ -277,7 +282,6 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||
|
||||
passHostHeader := getBoolValue(i.Annotations, annotationKubernetesPreserveHost, !p.DisablePassHostHeaders)
|
||||
passTLSCert := getBoolValue(i.Annotations, annotationKubernetesPassTLSCert, p.EnablePassTLSCert) // Deprecated
|
||||
entryPoints := getSliceStringValue(i.Annotations, annotationKubernetesFrontendEntryPoints)
|
||||
|
||||
frontend = &types.Frontend{
|
||||
Backend: baseName,
|
||||
@@ -502,40 +506,65 @@ func (p *Provider) addGlobalBackend(cl Client, i *extensionsv1beta1.Ingress, tem
|
||||
templateObjects.Backends[defaultBackendName].Buffering = getBuffering(service)
|
||||
templateObjects.Backends[defaultBackendName].ResponseForwarding = getResponseForwarding(service)
|
||||
|
||||
endpoints, exists, err := cl.GetEndpoints(service.Namespace, service.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retrieving endpoint information from k8s API %s/%s: %v", service.Namespace, service.Name, err)
|
||||
}
|
||||
if !exists {
|
||||
return fmt.Errorf("endpoints not found for %s/%s", service.Namespace, service.Name)
|
||||
}
|
||||
if len(endpoints.Subsets) == 0 {
|
||||
return fmt.Errorf("endpoints not available for %s/%s", service.Namespace, service.Name)
|
||||
}
|
||||
for _, port := range service.Spec.Ports {
|
||||
|
||||
for _, subset := range endpoints.Subsets {
|
||||
endpointPort := endpointPortNumber(corev1.ServicePort{Protocol: "TCP", Port: int32(i.Spec.Backend.ServicePort.IntValue())}, subset.Ports)
|
||||
if endpointPort == 0 {
|
||||
// endpoint port does not match service.
|
||||
continue
|
||||
}
|
||||
// We have to treat external-name service differently here b/c it doesn't have any endpoints
|
||||
if service.Spec.Type == corev1.ServiceTypeExternalName {
|
||||
|
||||
protocol := "http"
|
||||
for _, address := range subset.Addresses {
|
||||
if endpointPort == 443 || strings.HasPrefix(i.Spec.Backend.ServicePort.String(), "https") {
|
||||
protocol := "http"
|
||||
if port.Port == 443 || strings.HasPrefix(port.Name, "https") {
|
||||
protocol = "https"
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s://%s", protocol, net.JoinHostPort(address.IP, strconv.FormatInt(int64(endpointPort), 10)))
|
||||
name := url
|
||||
if address.TargetRef != nil && address.TargetRef.Name != "" {
|
||||
name = address.TargetRef.Name
|
||||
url := protocol + "://" + service.Spec.ExternalName
|
||||
if port.Port != 443 && port.Port != 80 {
|
||||
url = fmt.Sprintf("%s:%d", url, port.Port)
|
||||
}
|
||||
|
||||
templateObjects.Backends[defaultBackendName].Servers[name] = types.Server{
|
||||
templateObjects.Backends[defaultBackendName].Servers[url] = types.Server{
|
||||
URL: url,
|
||||
Weight: label.DefaultWeight,
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
endpoints, exists, err := cl.GetEndpoints(service.Namespace, service.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retrieving endpoint information from k8s API %s/%s: %v", service.Namespace, service.Name, err)
|
||||
}
|
||||
if !exists {
|
||||
return fmt.Errorf("endpoints not found for %s/%s", service.Namespace, service.Name)
|
||||
}
|
||||
if len(endpoints.Subsets) == 0 {
|
||||
return fmt.Errorf("endpoints not available for %s/%s", service.Namespace, service.Name)
|
||||
}
|
||||
|
||||
for _, subset := range endpoints.Subsets {
|
||||
|
||||
endpointPort := endpointPortNumber(port, subset.Ports)
|
||||
if endpointPort == 0 {
|
||||
// endpoint port does not match service.
|
||||
continue
|
||||
}
|
||||
|
||||
protocol := "http"
|
||||
for _, address := range subset.Addresses {
|
||||
if endpointPort == 443 || strings.HasPrefix(i.Spec.Backend.ServicePort.String(), "https") {
|
||||
protocol = "https"
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s://%s", protocol, net.JoinHostPort(address.IP, strconv.FormatInt(int64(endpointPort), 10)))
|
||||
name := url
|
||||
if address.TargetRef != nil && address.TargetRef.Name != "" {
|
||||
name = address.TargetRef.Name
|
||||
}
|
||||
|
||||
templateObjects.Backends[defaultBackendName].Servers[name] = types.Server{
|
||||
URL: url,
|
||||
Weight: label.DefaultWeight,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -284,6 +284,59 @@ func TestLoadIngresses(t *testing.T) {
|
||||
assert.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestLoadGlobalIngressWithExternalName(t *testing.T) {
|
||||
ingresses := []*extensionsv1beta1.Ingress{
|
||||
buildIngress(
|
||||
iNamespace("testing"),
|
||||
iSpecBackends(iSpecBackend(iIngressBackend("service1", intstr.FromInt(80)))),
|
||||
),
|
||||
}
|
||||
|
||||
services := []*corev1.Service{
|
||||
buildService(
|
||||
sName("service1"),
|
||||
sNamespace("testing"),
|
||||
sUID("1"),
|
||||
sSpec(
|
||||
sType("ExternalName"),
|
||||
sExternalName("some-external-name"),
|
||||
sPorts(sPort(80, ""))),
|
||||
),
|
||||
}
|
||||
|
||||
watchChan := make(chan interface{})
|
||||
client := clientMock{
|
||||
ingresses: ingresses,
|
||||
services: services,
|
||||
watchChan: watchChan,
|
||||
}
|
||||
provider := Provider{}
|
||||
|
||||
actual, err := provider.loadIngresses(client)
|
||||
require.NoError(t, err, "error loading ingresses")
|
||||
|
||||
expected := buildConfiguration(
|
||||
backends(
|
||||
backend("global-default-backend",
|
||||
lbMethod("wrr"),
|
||||
servers(
|
||||
server("http://some-external-name", weight(1)),
|
||||
),
|
||||
),
|
||||
),
|
||||
frontends(
|
||||
frontend("global-default-backend",
|
||||
frontendName("global-default-frontend"),
|
||||
passHostHeader(),
|
||||
routes(
|
||||
route("/", "PathPrefix:/"),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
assert.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestLoadGlobalIngressWithPortNumbers(t *testing.T) {
|
||||
ingresses := []*extensionsv1beta1.Ingress{
|
||||
buildIngress(
|
||||
@@ -374,7 +427,7 @@ func TestLoadGlobalIngressWithHttpsPortNames(t *testing.T) {
|
||||
eUID("1"),
|
||||
subset(
|
||||
eAddresses(eAddress("10.10.0.1")),
|
||||
ePorts(ePort(8080, ""))),
|
||||
ePorts(ePort(8080, "https-global"))),
|
||||
),
|
||||
}
|
||||
|
||||
@@ -1456,7 +1509,7 @@ rateset:
|
||||
server("http://example.com", weight(1))),
|
||||
lbMethod("wrr"),
|
||||
),
|
||||
backend("other/",
|
||||
backend("http-https_other/",
|
||||
servers(
|
||||
server("http://example.com", weight(1)),
|
||||
server("http://example.com", weight(1))),
|
||||
@@ -1564,7 +1617,7 @@ rateset:
|
||||
route("/stuff", "PathPrefix:/stuff"),
|
||||
route("other", "Host:other")),
|
||||
),
|
||||
frontend("other/",
|
||||
frontend("http-https_other/",
|
||||
passHostHeader(),
|
||||
entryPoints("http", "https"),
|
||||
routes(
|
||||
@@ -2783,24 +2836,24 @@ func TestTLSSecretLoad(t *testing.T) {
|
||||
|
||||
expected := buildConfiguration(
|
||||
backends(
|
||||
backend("example.com",
|
||||
backend("ep1-ep2_example.com",
|
||||
servers(),
|
||||
lbMethod("wrr"),
|
||||
),
|
||||
backend("example.org",
|
||||
backend("ep1-ep2_example.org",
|
||||
servers(),
|
||||
lbMethod("wrr"),
|
||||
),
|
||||
),
|
||||
frontends(
|
||||
frontend("example.com",
|
||||
frontend("ep1-ep2_example.com",
|
||||
entryPoints("ep1", "ep2"),
|
||||
passHostHeader(),
|
||||
routes(
|
||||
route("example.com", "Host:example.com"),
|
||||
),
|
||||
),
|
||||
frontend("example.org",
|
||||
frontend("ep1-ep2_example.org",
|
||||
entryPoints("ep1", "ep2"),
|
||||
passHostHeader(),
|
||||
routes(
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if [ -n "$TRAVIS_COMMIT" ]; then
|
||||
echo "Deploying PR..."
|
||||
else
|
||||
echo "Skipping deploy PR"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# create docker image containous/traefik
|
||||
echo "Updating docker containous/traefik image..."
|
||||
docker login -u $DOCKER_USER -p $DOCKER_PASS
|
||||
docker tag containous/traefik containous/traefik:${TRAVIS_COMMIT}
|
||||
docker push containous/traefik:${TRAVIS_COMMIT}
|
||||
docker tag containous/traefik containous/traefik:experimental
|
||||
docker push containous/traefik:experimental
|
||||
|
||||
echo "Deployed"
|
||||
@@ -22,7 +22,7 @@ ssh-add ~/.ssh/traefiker_rsa
|
||||
echo "Updating traefik-library-imag repo..."
|
||||
git clone git@github.com:containous/traefik-library-image.git
|
||||
cd traefik-library-image
|
||||
./update.sh $VERSION
|
||||
./updatev1.sh $VERSION
|
||||
git add -A
|
||||
echo $VERSION | git commit --file -
|
||||
echo $VERSION | git tag -a $VERSION --file -
|
||||
|
||||
@@ -33,9 +33,9 @@ import (
|
||||
traefiktls "github.com/containous/traefik/tls"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/containous/traefik/whitelist"
|
||||
"github.com/go-acme/lego/challenge/tlsalpn01"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/negroni"
|
||||
"github.com/xenolf/lego/challenge/tlsalpn01"
|
||||
)
|
||||
|
||||
var httpServerLogger = stdlog.New(log.WriterLevel(logrus.DebugLevel), "", 0)
|
||||
|
||||
@@ -112,6 +112,15 @@ func (s *Server) buildMiddlewares(frontendName string, frontend *types.Frontend,
|
||||
middle = append(middle, handler)
|
||||
}
|
||||
|
||||
// TLSClientHeaders
|
||||
tlsClientHeadersMiddleware := middlewares.NewTLSClientHeaders(frontend)
|
||||
if tlsClientHeadersMiddleware != nil {
|
||||
log.Debugf("Adding TLSClientHeaders middleware for frontend %s", frontendName)
|
||||
|
||||
handler := s.tracingMiddleware.NewNegroniHandlerWrapper("TLSClientHeaders", tlsClientHeadersMiddleware, false)
|
||||
middle = append(middle, handler)
|
||||
}
|
||||
|
||||
// Authentication
|
||||
if frontend.Auth != nil {
|
||||
authMiddleware, err := mauth.NewAuthenticator(frontend.Auth, s.tracingMiddleware)
|
||||
@@ -123,15 +132,6 @@ func (s *Server) buildMiddlewares(frontendName string, frontend *types.Frontend,
|
||||
middle = append(middle, handler)
|
||||
}
|
||||
|
||||
// TLSClientHeaders
|
||||
tlsClientHeadersMiddleware := middlewares.NewTLSClientHeaders(frontend)
|
||||
if tlsClientHeadersMiddleware != nil {
|
||||
log.Debugf("Adding TLSClientHeaders middleware for frontend %s", frontendName)
|
||||
|
||||
handler := s.tracingMiddleware.NewNegroniHandlerWrapper("TLSClientHeaders", tlsClientHeadersMiddleware, false)
|
||||
middle = append(middle, handler)
|
||||
}
|
||||
|
||||
return middle, buildModifyResponse(secureMiddleware, headerMiddleware), postConfig, nil
|
||||
}
|
||||
|
||||
|
||||
110
vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/push/push_notice_to_android.go
generated
vendored
110
vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/push/push_notice_to_android.go
generated
vendored
@@ -1,110 +0,0 @@
|
||||
package push
|
||||
|
||||
//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.
|
||||
//
|
||||
// Code generated by Alibaba Cloud SDK Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
// PushNoticeToAndroid invokes the push.PushNoticeToAndroid API synchronously
|
||||
// api document: https://help.aliyun.com/api/push/pushnoticetoandroid.html
|
||||
func (client *Client) PushNoticeToAndroid(request *PushNoticeToAndroidRequest) (response *PushNoticeToAndroidResponse, err error) {
|
||||
response = CreatePushNoticeToAndroidResponse()
|
||||
err = client.DoAction(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
// PushNoticeToAndroidWithChan invokes the push.PushNoticeToAndroid API asynchronously
|
||||
// api document: https://help.aliyun.com/api/push/pushnoticetoandroid.html
|
||||
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
|
||||
func (client *Client) PushNoticeToAndroidWithChan(request *PushNoticeToAndroidRequest) (<-chan *PushNoticeToAndroidResponse, <-chan error) {
|
||||
responseChan := make(chan *PushNoticeToAndroidResponse, 1)
|
||||
errChan := make(chan error, 1)
|
||||
err := client.AddAsyncTask(func() {
|
||||
defer close(responseChan)
|
||||
defer close(errChan)
|
||||
response, err := client.PushNoticeToAndroid(request)
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
} else {
|
||||
responseChan <- response
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
close(responseChan)
|
||||
close(errChan)
|
||||
}
|
||||
return responseChan, errChan
|
||||
}
|
||||
|
||||
// PushNoticeToAndroidWithCallback invokes the push.PushNoticeToAndroid API asynchronously
|
||||
// api document: https://help.aliyun.com/api/push/pushnoticetoandroid.html
|
||||
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
|
||||
func (client *Client) PushNoticeToAndroidWithCallback(request *PushNoticeToAndroidRequest, callback func(response *PushNoticeToAndroidResponse, err error)) <-chan int {
|
||||
result := make(chan int, 1)
|
||||
err := client.AddAsyncTask(func() {
|
||||
var response *PushNoticeToAndroidResponse
|
||||
var err error
|
||||
defer close(result)
|
||||
response, err = client.PushNoticeToAndroid(request)
|
||||
callback(response, err)
|
||||
result <- 1
|
||||
})
|
||||
if err != nil {
|
||||
defer close(result)
|
||||
callback(nil, err)
|
||||
result <- 0
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// PushNoticeToAndroidRequest is the request struct for api PushNoticeToAndroid
|
||||
type PushNoticeToAndroidRequest struct {
|
||||
*requests.RpcRequest
|
||||
AppKey requests.Integer `position:"Query" name:"AppKey"`
|
||||
Target string `position:"Query" name:"Target"`
|
||||
TargetValue string `position:"Query" name:"TargetValue"`
|
||||
Title string `position:"Query" name:"Title"`
|
||||
Body string `position:"Query" name:"Body"`
|
||||
JobKey string `position:"Query" name:"JobKey"`
|
||||
ExtParameters string `position:"Query" name:"ExtParameters"`
|
||||
}
|
||||
|
||||
// PushNoticeToAndroidResponse is the response struct for api PushNoticeToAndroid
|
||||
type PushNoticeToAndroidResponse struct {
|
||||
*responses.BaseResponse
|
||||
RequestId string `json:"RequestId" xml:"RequestId"`
|
||||
MessageId string `json:"MessageId" xml:"MessageId"`
|
||||
}
|
||||
|
||||
// CreatePushNoticeToAndroidRequest creates a request to invoke PushNoticeToAndroid API
|
||||
func CreatePushNoticeToAndroidRequest() (request *PushNoticeToAndroidRequest) {
|
||||
request = &PushNoticeToAndroidRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
request.InitWithApiInfo("Push", "2016-08-01", "PushNoticeToAndroid", "", "")
|
||||
return
|
||||
}
|
||||
|
||||
// CreatePushNoticeToAndroidResponse creates a response to parse from PushNoticeToAndroid response
|
||||
func CreatePushNoticeToAndroidResponse() (response *PushNoticeToAndroidResponse) {
|
||||
response = &PushNoticeToAndroidResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
111
vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/push/push_notice_toi_os.go
generated
vendored
111
vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/push/push_notice_toi_os.go
generated
vendored
@@ -1,111 +0,0 @@
|
||||
package push
|
||||
|
||||
//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.
|
||||
//
|
||||
// Code generated by Alibaba Cloud SDK Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
||||
)
|
||||
|
||||
// PushNoticeToiOS invokes the push.PushNoticeToiOS API synchronously
|
||||
// api document: https://help.aliyun.com/api/push/pushnoticetoios.html
|
||||
func (client *Client) PushNoticeToiOS(request *PushNoticeToiOSRequest) (response *PushNoticeToiOSResponse, err error) {
|
||||
response = CreatePushNoticeToiOSResponse()
|
||||
err = client.DoAction(request, response)
|
||||
return
|
||||
}
|
||||
|
||||
// PushNoticeToiOSWithChan invokes the push.PushNoticeToiOS API asynchronously
|
||||
// api document: https://help.aliyun.com/api/push/pushnoticetoios.html
|
||||
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
|
||||
func (client *Client) PushNoticeToiOSWithChan(request *PushNoticeToiOSRequest) (<-chan *PushNoticeToiOSResponse, <-chan error) {
|
||||
responseChan := make(chan *PushNoticeToiOSResponse, 1)
|
||||
errChan := make(chan error, 1)
|
||||
err := client.AddAsyncTask(func() {
|
||||
defer close(responseChan)
|
||||
defer close(errChan)
|
||||
response, err := client.PushNoticeToiOS(request)
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
} else {
|
||||
responseChan <- response
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
close(responseChan)
|
||||
close(errChan)
|
||||
}
|
||||
return responseChan, errChan
|
||||
}
|
||||
|
||||
// PushNoticeToiOSWithCallback invokes the push.PushNoticeToiOS API asynchronously
|
||||
// api document: https://help.aliyun.com/api/push/pushnoticetoios.html
|
||||
// asynchronous document: https://help.aliyun.com/document_detail/66220.html
|
||||
func (client *Client) PushNoticeToiOSWithCallback(request *PushNoticeToiOSRequest, callback func(response *PushNoticeToiOSResponse, err error)) <-chan int {
|
||||
result := make(chan int, 1)
|
||||
err := client.AddAsyncTask(func() {
|
||||
var response *PushNoticeToiOSResponse
|
||||
var err error
|
||||
defer close(result)
|
||||
response, err = client.PushNoticeToiOS(request)
|
||||
callback(response, err)
|
||||
result <- 1
|
||||
})
|
||||
if err != nil {
|
||||
defer close(result)
|
||||
callback(nil, err)
|
||||
result <- 0
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// PushNoticeToiOSRequest is the request struct for api PushNoticeToiOS
|
||||
type PushNoticeToiOSRequest struct {
|
||||
*requests.RpcRequest
|
||||
AppKey requests.Integer `position:"Query" name:"AppKey"`
|
||||
Target string `position:"Query" name:"Target"`
|
||||
TargetValue string `position:"Query" name:"TargetValue"`
|
||||
ApnsEnv string `position:"Query" name:"ApnsEnv"`
|
||||
Title string `position:"Query" name:"Title"`
|
||||
Body string `position:"Query" name:"Body"`
|
||||
JobKey string `position:"Query" name:"JobKey"`
|
||||
ExtParameters string `position:"Query" name:"ExtParameters"`
|
||||
}
|
||||
|
||||
// PushNoticeToiOSResponse is the response struct for api PushNoticeToiOS
|
||||
type PushNoticeToiOSResponse struct {
|
||||
*responses.BaseResponse
|
||||
RequestId string `json:"RequestId" xml:"RequestId"`
|
||||
MessageId string `json:"MessageId" xml:"MessageId"`
|
||||
}
|
||||
|
||||
// CreatePushNoticeToiOSRequest creates a request to invoke PushNoticeToiOS API
|
||||
func CreatePushNoticeToiOSRequest() (request *PushNoticeToiOSRequest) {
|
||||
request = &PushNoticeToiOSRequest{
|
||||
RpcRequest: &requests.RpcRequest{},
|
||||
}
|
||||
request.InitWithApiInfo("Push", "2016-08-01", "PushNoticeToiOS", "", "")
|
||||
return
|
||||
}
|
||||
|
||||
// CreatePushNoticeToiOSResponse creates a response to parse from PushNoticeToiOS response
|
||||
func CreatePushNoticeToiOSResponse() (response *PushNoticeToiOSResponse) {
|
||||
response = &PushNoticeToiOSResponse{
|
||||
BaseResponse: &responses.BaseResponse{},
|
||||
}
|
||||
return
|
||||
}
|
||||
9
vendor/github.com/containous/staert/toml.go
generated
vendored
9
vendor/github.com/containous/staert/toml.go
generated
vendored
@@ -47,10 +47,7 @@ func (ts *TomlSource) Parse(cmd *flaeg.Command) (*flaeg.Command, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
flgArgs, hasUnderField, err := generateArgs(metadata, boolFlags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
flgArgs, hasUnderField := generateArgs(metadata, boolFlags)
|
||||
|
||||
err = flaeg.Load(cmd.Config, cmd.DefaultPointersConfig, flgArgs)
|
||||
if err != nil && err != flaeg.ErrParserNotFound {
|
||||
@@ -89,7 +86,7 @@ func findFile(filename string, dirNFile []string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func generateArgs(metadata toml.MetaData, flags []string) ([]string, bool, error) {
|
||||
func generateArgs(metadata toml.MetaData, flags []string) ([]string, bool) {
|
||||
var flgArgs []string
|
||||
keys := metadata.Keys()
|
||||
hasUnderField := false
|
||||
@@ -117,5 +114,5 @@ func generateArgs(metadata toml.MetaData, flags []string) ([]string, bool, error
|
||||
}
|
||||
}
|
||||
|
||||
return flgArgs, hasUnderField, nil
|
||||
return flgArgs, hasUnderField
|
||||
}
|
||||
|
||||
5
vendor/github.com/containous/traefik-extra-service-fabric/servicefabric_config.go
generated
vendored
5
vendor/github.com/containous/traefik-extra-service-fabric/servicefabric_config.go
generated
vendored
@@ -48,6 +48,7 @@ func (p *Provider) buildConfiguration(services []ServiceItemExtended) (*types.Co
|
||||
"getWhiteList": getWhiteList,
|
||||
"getHeaders": getHeaders,
|
||||
"getRedirect": getRedirect,
|
||||
"getErrorPages": getErrorPages,
|
||||
|
||||
// SF Service Grouping
|
||||
"getGroupedServices": getFuncServicesGroupedByLabel(traefikSFGroupName),
|
||||
@@ -172,3 +173,7 @@ func getCircuitBreaker(service ServiceItemExtended) *types.CircuitBreaker {
|
||||
func getLoadBalancer(service ServiceItemExtended) *types.LoadBalancer {
|
||||
return label.GetLoadBalancer(service.Labels)
|
||||
}
|
||||
|
||||
func getErrorPages(service ServiceItemExtended) map[string]*types.ErrorPage {
|
||||
return label.GetErrorPages(service.Labels)
|
||||
}
|
||||
|
||||
13
vendor/github.com/containous/traefik-extra-service-fabric/servicefabric_tmpl.go
generated
vendored
13
vendor/github.com/containous/traefik-extra-service-fabric/servicefabric_tmpl.go
generated
vendored
@@ -162,6 +162,19 @@ const tmpl = `
|
||||
permanent = {{ $redirect.Permanent }}
|
||||
{{end}}
|
||||
|
||||
{{ $errorPages := getErrorPages $service }}
|
||||
{{if $errorPages }}
|
||||
[frontends."frontend-{{ $frontendName }}".errors]
|
||||
{{range $pageName, $page := $errorPages }}
|
||||
[frontends."frontend-{{ $frontendName }}".errors."{{ $pageName }}"]
|
||||
status = [{{range $page.Status }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
backend = "{{ $page.Backend }}"
|
||||
query = "{{ $page.Query }}"
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{ $headers := getHeaders $service }}
|
||||
{{if $headers }}
|
||||
[frontends."frontend-{{ $frontendName }}".headers]
|
||||
|
||||
105
vendor/github.com/exoscale/egoscale/accounts.go
generated
vendored
105
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"`
|
||||
@@ -74,55 +54,23 @@ type Account struct {
|
||||
// ListRequest builds the ListAccountsGroups request
|
||||
func (a Account) ListRequest() (ListCommand, error) {
|
||||
return &ListAccounts{
|
||||
ID: a.ID,
|
||||
DomainID: a.DomainID,
|
||||
AccountType: a.AccountType,
|
||||
State: a.State,
|
||||
ID: a.ID,
|
||||
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"`
|
||||
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"`
|
||||
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."`
|
||||
_ 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
|
||||
}
|
||||
}
|
||||
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)"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
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."`
|
||||
_ bool `name:"listAccounts" description:"Lists accounts and provides detailed account information for listed accounts"`
|
||||
}
|
||||
|
||||
// ListAccountsResponse represents a list of accounts
|
||||
@@ -130,32 +78,3 @@ 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]]
|
||||
}
|
||||
83
vendor/github.com/exoscale/egoscale/addresses.go
generated
vendored
83
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."`
|
||||
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."`
|
||||
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"`
|
||||
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"`
|
||||
_ 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
106
vendor/github.com/exoscale/egoscale/affinity_groups.go
generated
vendored
106
vendor/github.com/exoscale/egoscale/affinity_groups.go
generated
vendored
@@ -11,14 +11,12 @@ import (
|
||||
// Affinity and Anti-Affinity groups provide a way to influence where VMs should run.
|
||||
// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/virtual_machines.html#affinity-groups
|
||||
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"`
|
||||
VirtualMachineIDs []string `json:"virtualmachineIds,omitempty" doc:"virtual machine Ids associated with this affinity group"`
|
||||
Account string `json:"account,omitempty" doc:"the account owning the affinity group"`
|
||||
Description string `json:"description,omitempty" doc:"the description 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"`
|
||||
VirtualMachineIDs []UUID `json:"virtualmachineIds,omitempty" doc:"virtual machine Ids associated with this affinity group"`
|
||||
}
|
||||
|
||||
// ListRequest builds the ListAffinityGroups request
|
||||
@@ -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"`
|
||||
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)
|
||||
}
|
||||
|
||||
39
vendor/github.com/exoscale/egoscale/async_jobs.go
generated
vendored
39
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,31 +45,26 @@ 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"`
|
||||
_ bool `name:"listAsyncJobs" description:"Lists all pending asynchronous jobs for the account."`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
StartDate string `json:"startdate,omitempty" doc:"the start date of the async job"`
|
||||
_ bool `name:"listAsyncJobs" description:"Lists all pending asynchronous jobs for the account."`
|
||||
}
|
||||
|
||||
// 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)
|
||||
Count int `json:"count"`
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
117
vendor/github.com/exoscale/egoscale/client.go
generated
vendored
117
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{
|
||||
ErrorCode: ParamError,
|
||||
ErrorText: fmt.Sprintf("not found, query: %s", payload),
|
||||
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)
|
||||
|
||||
if g == nil || reflect.ValueOf(g).IsNil() {
|
||||
return s, fmt.Errorf("g Listable shouldn't be nil, got %#v", g)
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
if g == nil || reflect.ValueOf(g).IsNil() {
|
||||
err = fmt.Errorf("g Listable shouldn't be nil, got %#v", g)
|
||||
return
|
||||
}
|
||||
|
||||
panic(e)
|
||||
}
|
||||
}()
|
||||
|
||||
req, e := g.ListRequest()
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
|
||||
req, err := g.ListRequest()
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
62
vendor/github.com/exoscale/egoscale/events.go
generated
vendored
62
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,28 +13,44 @@ 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" `
|
||||
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)"`
|
||||
_ bool `name:"listEvents" description:"A command to list events."`
|
||||
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"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
Level string `json:"level,omitempty" doc:"the event level (INFO, WARN, ERROR)"`
|
||||
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)"`
|
||||
_ bool `name:"listEvents" description:"A command to list events."`
|
||||
}
|
||||
|
||||
// ListEventsResponse represents a response of a list query
|
||||
@@ -45,13 +59,13 @@ 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 {
|
||||
_ bool `name:"listEventTypes" description:"List Event Types"`
|
||||
Page int `json:"page,omitempty"` // fake
|
||||
PageSize int `json:"pagesize,omitempty"` // fake
|
||||
_ bool `name:"listEventTypes" description:"List Event Types"`
|
||||
}
|
||||
|
||||
// ListEventTypesResponse represents a response of a list query
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
106
vendor/github.com/exoscale/egoscale/networks.go
generated
vendored
106
vendor/github.com/exoscale/egoscale/networks.go
generated
vendored
@@ -1,7 +1,6 @@
|
||||
package egoscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
)
|
||||
@@ -16,12 +15,10 @@ 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"`
|
||||
IP6CIDR *CIDR `json:"ip6cidr,omitempty" doc:"the cidr of IPv6 network"`
|
||||
@@ -44,6 +41,7 @@ type Network struct {
|
||||
RestartRequired bool `json:"restartrequired,omitempty" doc:"true network requires restart"`
|
||||
Service []Service `json:"service,omitempty" doc:"the list of services"`
|
||||
SpecifyIPRanges bool `json:"specifyipranges,omitempty" doc:"true if network supports specifying ip ranges, false otherwise"`
|
||||
StartIP net.IP `json:"startip,omitempty" doc:"the beginning IP address in the network IP range. Required for managed networks."`
|
||||
State string `json:"state,omitempty" doc:"state of the network"`
|
||||
StrechedL2Subnet bool `json:"strechedl2subnet,omitempty" doc:"true if network can span multiple zones"`
|
||||
SubdomainAccess bool `json:"subdomainaccess,omitempty" doc:"true if users from subdomains can access the domain level network"`
|
||||
@@ -60,9 +58,8 @@ 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,
|
||||
TrafficType: network.TrafficType,
|
||||
Type: network.Type,
|
||||
@@ -110,30 +107,27 @@ 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. If not specified, will be defaulted to startIP"`
|
||||
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"`
|
||||
IP6CIDR *CIDR `json:"ip6cidr,omitempty" doc:"the CIDR of IPv6 network, must be at least /64"`
|
||||
IP6Gateway net.IP `json:"ip6gateway,omitempty" doc:"the gateway of the IPv6 network. Required for Shared networks and Isolated networks when it belongs to VPC"`
|
||||
IsolatedPVlan string `json:"isolatedpvlan,omitempty" doc:"the isolated private vlan for this network"`
|
||||
Name string `json:"name,omitempty" doc:"the name of the network"` // This field is required but might be empty
|
||||
Netmask net.IP `json:"netmask,omitempty" doc:"the netmask of the network. Required for Shared networks and Isolated networks when it belongs to VPC"`
|
||||
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" doc:"the network offering id"`
|
||||
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"`
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -150,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)
|
||||
}
|
||||
|
||||
@@ -177,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)
|
||||
}
|
||||
|
||||
@@ -192,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."`
|
||||
}
|
||||
|
||||
@@ -229,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
|
||||
}
|
||||
}
|
||||
}
|
||||
48
vendor/github.com/exoscale/egoscale/request.go
generated
vendored
48
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,11 +32,17 @@ func (e booleanResponse) Error() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// XXX: addIpToNic, activateIp6, restorevmresponse are kind of special
|
||||
var responseKeys = map[string]string{
|
||||
"addiptonicresponse": "addiptovmnicresponse",
|
||||
"activateip6response": "activateip6nicresponse",
|
||||
"restorevirtualmachineresponse": "restorevmresponse",
|
||||
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) {
|
||||
@@ -59,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
|
||||
}
|
||||
@@ -67,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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,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,
|
||||
@@ -138,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 {
|
||||
@@ -177,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()
|
||||
}
|
||||
|
||||
@@ -191,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()
|
||||
}
|
||||
|
||||
@@ -208,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)
|
||||
}
|
||||
@@ -277,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 {
|
||||
@@ -291,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)
|
||||
}
|
||||
|
||||
131
vendor/github.com/exoscale/egoscale/runstatus.go
generated
vendored
Normal file
131
vendor/github.com/exoscale/egoscale/runstatus.go
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
package egoscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"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"
|
||||
|
||||
// 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 %d content-type expected to be "application/json", got %q`, resp.StatusCode, 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
|
||||
}
|
||||
175
vendor/github.com/exoscale/egoscale/runstatus_incident.go
generated
vendored
Normal file
175
vendor/github.com/exoscale/egoscale/runstatus_incident.go
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
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 {
|
||||
Next string `json:"next"`
|
||||
Previous string `json:"previous"`
|
||||
Incidents []RunstatusIncident `json:"results"`
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
for i := range page.Incidents {
|
||||
j := &page.Incidents[i]
|
||||
if j.Match(incident) {
|
||||
return j, 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)
|
||||
}
|
||||
|
||||
results := make([]RunstatusIncident, 0)
|
||||
|
||||
var err error
|
||||
client.PaginateRunstatusIncidents(ctx, page, func(incident *RunstatusIncident, e error) bool {
|
||||
if e != nil {
|
||||
err = e
|
||||
return false
|
||||
}
|
||||
|
||||
results = append(results, *incident)
|
||||
return true
|
||||
})
|
||||
|
||||
return results, err
|
||||
}
|
||||
|
||||
// PaginateRunstatusIncidents paginate Incidents
|
||||
func (client *Client) PaginateRunstatusIncidents(ctx context.Context, page RunstatusPage, callback func(*RunstatusIncident, error) bool) {
|
||||
if page.IncidentsURL == "" {
|
||||
callback(nil, fmt.Errorf("empty Incidents URL for %#v", page))
|
||||
return
|
||||
}
|
||||
|
||||
incidentsURL := page.IncidentsURL
|
||||
for incidentsURL != "" {
|
||||
resp, err := client.runstatusRequest(ctx, incidentsURL, nil, "GET")
|
||||
if err != nil {
|
||||
callback(nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
var is *RunstatusIncidentList
|
||||
if err := json.Unmarshal(resp, &is); err != nil {
|
||||
callback(nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
for i := range is.Incidents {
|
||||
if cont := callback(&is.Incidents[i], nil); !cont {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
incidentsURL = is.Next
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
208
vendor/github.com/exoscale/egoscale/runstatus_maintenance.go
generated
vendored
Normal file
208
vendor/github.com/exoscale/egoscale/runstatus_maintenance.go
generated
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
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 {
|
||||
Next string `json:"next"`
|
||||
Previous string `json:"previous"`
|
||||
Maintenances []RunstatusMaintenance `json:"results"`
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
for i := range page.Maintenances {
|
||||
m := &page.Maintenances[i]
|
||||
if m.Match(maintenance) {
|
||||
if err := m.FakeID(); err != nil {
|
||||
log.Printf("bad fake ID for %#v, %s", m, err)
|
||||
}
|
||||
return m, 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)
|
||||
}
|
||||
|
||||
results := make([]RunstatusMaintenance, 0)
|
||||
|
||||
var err error
|
||||
client.PaginateRunstatusMaintenances(ctx, page, func(maintenance *RunstatusMaintenance, e error) bool {
|
||||
if e != nil {
|
||||
err = e
|
||||
return false
|
||||
}
|
||||
|
||||
results = append(results, *maintenance)
|
||||
return true
|
||||
})
|
||||
|
||||
return results, err
|
||||
}
|
||||
|
||||
// PaginateRunstatusMaintenances paginate Maintenances
|
||||
func (client *Client) PaginateRunstatusMaintenances(ctx context.Context, page RunstatusPage, callback func(*RunstatusMaintenance, error) bool) { // nolint: dupl
|
||||
if page.MaintenancesURL == "" {
|
||||
callback(nil, fmt.Errorf("empty Maintenances URL for %#v", page))
|
||||
return
|
||||
}
|
||||
|
||||
maintenancesURL := page.MaintenancesURL
|
||||
for maintenancesURL != "" {
|
||||
resp, err := client.runstatusRequest(ctx, maintenancesURL, nil, "GET")
|
||||
if err != nil {
|
||||
callback(nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
var ms *RunstatusMaintenanceList
|
||||
if err := json.Unmarshal(resp, &ms); err != nil {
|
||||
callback(nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
for i := range ms.Maintenances {
|
||||
if err := ms.Maintenances[i].FakeID(); err != nil {
|
||||
log.Printf("bad fake ID for %#v, %s", ms.Maintenances[i], err)
|
||||
}
|
||||
if cont := callback(&ms.Maintenances[i], nil); !cont {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
maintenancesURL = ms.Next
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
168
vendor/github.com/exoscale/egoscale/runstatus_page.go
generated
vendored
Normal file
168
vendor/github.com/exoscale/egoscale/runstatus_page.go
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
package egoscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 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 {
|
||||
Next string `json:"next"`
|
||||
Previous string `json:"previous"`
|
||||
Pages []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 client.getRunstatusPage(ctx, ps[i].URL)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
return p.Pages, nil
|
||||
}
|
||||
|
||||
//PaginateRunstatusPages paginate on runstatus pages
|
||||
func (client *Client) PaginateRunstatusPages(ctx context.Context, callback func(pages []RunstatusPage, e error) bool) {
|
||||
pageURL := client.Endpoint + runstatusPagesURL
|
||||
for pageURL != "" {
|
||||
resp, err := client.runstatusRequest(ctx, pageURL, nil, "GET")
|
||||
if err != nil {
|
||||
callback(nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
var p *RunstatusPageList
|
||||
if err := json.Unmarshal(resp, &p); err != nil {
|
||||
callback(nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
if ok := callback(p.Pages, nil); ok {
|
||||
return
|
||||
}
|
||||
|
||||
pageURL = p.Next
|
||||
}
|
||||
}
|
||||
201
vendor/github.com/exoscale/egoscale/runstatus_service.go
generated
vendored
Normal file
201
vendor/github.com/exoscale/egoscale/runstatus_service.go
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
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 {
|
||||
Next string `json:"next"`
|
||||
Previous string `json:"previous"`
|
||||
Services []RunstatusService `json:"results"`
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
for i := range page.Services {
|
||||
s := &page.Services[i]
|
||||
if s.Match(service) {
|
||||
if err := s.FakeID(); err != nil {
|
||||
log.Printf("bad fake ID for %#v, %s", s, err)
|
||||
}
|
||||
return s, 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)
|
||||
}
|
||||
|
||||
results := make([]RunstatusService, 0)
|
||||
|
||||
var err error
|
||||
client.PaginateRunstatusServices(ctx, page, func(service *RunstatusService, e error) bool {
|
||||
if e != nil {
|
||||
err = e
|
||||
return false
|
||||
}
|
||||
|
||||
results = append(results, *service)
|
||||
return true
|
||||
})
|
||||
|
||||
return results, err
|
||||
}
|
||||
|
||||
// PaginateRunstatusServices paginates Services
|
||||
func (client *Client) PaginateRunstatusServices(ctx context.Context, page RunstatusPage, callback func(*RunstatusService, error) bool) { // nolint: dupl
|
||||
if page.ServicesURL == "" {
|
||||
callback(nil, fmt.Errorf("empty Services URL for %#v", page))
|
||||
return
|
||||
}
|
||||
|
||||
servicesURL := page.ServicesURL
|
||||
for servicesURL != "" {
|
||||
resp, err := client.runstatusRequest(ctx, servicesURL, nil, "GET")
|
||||
if err != nil {
|
||||
callback(nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
var ss *RunstatusServiceList
|
||||
if err := json.Unmarshal(resp, &ss); err != nil {
|
||||
callback(nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
for i := range ss.Services {
|
||||
if err := ss.Services[i].FakeID(); err != nil {
|
||||
log.Printf("bad fake ID for %#v, %s", ss.Services[i], err)
|
||||
}
|
||||
|
||||
if cont := callback(&ss.Services[i], nil); !cont {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
servicesURL = ss.Next
|
||||
}
|
||||
}
|
||||
152
vendor/github.com/exoscale/egoscale/security_groups.go
generated
vendored
152
vendor/github.com/exoscale/egoscale/security_groups.go
generated
vendored
@@ -12,34 +12,22 @@ 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"`
|
||||
Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with the rule"`
|
||||
}
|
||||
|
||||
// ResourceType returns the type of the resource
|
||||
func (SecurityGroup) ResourceType() string {
|
||||
return "SecurityGroup"
|
||||
}
|
||||
|
||||
// UserSecurityGroup converts a SecurityGroup to a UserSecurityGroup
|
||||
func (sg SecurityGroup) UserSecurityGroup() UserSecurityGroup {
|
||||
return UserSecurityGroup{
|
||||
Account: sg.Account,
|
||||
Group: sg.Name,
|
||||
Group: sg.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// ListRequest builds the ListSecurityGroups request
|
||||
func (sg SecurityGroup) ListRequest() (ListCommand, error) {
|
||||
//TODO add tags
|
||||
req := &ListSecurityGroups{
|
||||
Account: sg.Account,
|
||||
DomainID: sg.DomainID,
|
||||
ID: sg.ID,
|
||||
SecurityGroupName: sg.Name,
|
||||
}
|
||||
@@ -53,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
|
||||
@@ -86,19 +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"`
|
||||
SecurityGroupName string `json:"securitygroupname,omitempty" doc:"security group name"`
|
||||
StartPort uint16 `json:"startport,omitempty" doc:"the starting port of the security group rule"`
|
||||
Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with the rule"`
|
||||
UserSecurityGroupList []UserSecurityGroup `json:"usersecuritygrouplist,omitempty"`
|
||||
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" 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"`
|
||||
}
|
||||
|
||||
// EgressRule represents the ingress rule
|
||||
@@ -106,8 +87,7 @@ type EgressRule IngressRule
|
||||
|
||||
// UserSecurityGroup represents the traffic of another security group
|
||||
type UserSecurityGroup struct {
|
||||
Group string `json:"group,omitempty"`
|
||||
Account string `json:"account,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
// String gives the UserSecurityGroup name
|
||||
@@ -118,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"`
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -182,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)
|
||||
}
|
||||
|
||||
@@ -200,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
|
||||
@@ -213,28 +196,27 @@ 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"`
|
||||
Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"lists security groups by virtual machine id"`
|
||||
_ bool `name:"listSecurityGroups" description:"Lists security groups"`
|
||||
ID *UUID `json:"id,omitempty" doc:"list the security group by the id provided"`
|
||||
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
SecurityGroupName string `json:"securitygroupname,omitempty" doc:"lists security groups by name"`
|
||||
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"lists security groups by virtual machine id"`
|
||||
_ bool `name:"listSecurityGroups" description:"Lists security groups"`
|
||||
}
|
||||
|
||||
// ListSecurityGroupsResponse represents a list of security groups
|
||||
@@ -242,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
|
||||
}
|
||||
}
|
||||
}
|
||||
438
vendor/github.com/exoscale/egoscale/serialization.go
generated
vendored
438
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,217 +79,165 @@ 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 {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got 0", typeof.Name(), n, val.Kind())
|
||||
}
|
||||
} else {
|
||||
params.Set(name, strconv.FormatFloat(v, 'f', -1, 64))
|
||||
}
|
||||
value, err = prepareFloat(val.Float(), required)
|
||||
|
||||
case reflect.String:
|
||||
v := val.String()
|
||||
if v == "" {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got \"\"", typeof.Name(), n, val.Kind())
|
||||
}
|
||||
} else {
|
||||
params.Set(name, v)
|
||||
}
|
||||
value, err = prepareString(val.String(), required)
|
||||
|
||||
case reflect.Bool:
|
||||
v := val.Bool()
|
||||
if !v {
|
||||
if required {
|
||||
params.Set(name, "false")
|
||||
}
|
||||
} else {
|
||||
params.Set(name, "true")
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if val.IsNil() {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty ptr", typeof.Name(), n, val.Kind())
|
||||
}
|
||||
} else {
|
||||
switch field.Type.Elem().Kind() {
|
||||
case reflect.Bool:
|
||||
params.Set(name, strconv.FormatBool(val.Elem().Bool()))
|
||||
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())
|
||||
}
|
||||
default:
|
||||
log.Printf("[SKIP] %s.%s (%v) not supported", typeof.Name(), n, field.Type.Elem().Kind())
|
||||
}
|
||||
}
|
||||
case reflect.Slice:
|
||||
switch field.Type.Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
switch field.Type {
|
||||
case reflect.TypeOf(net.IPv4zero):
|
||||
ip := (net.IP)(val.Bytes())
|
||||
if ip == nil || ip.Equal(net.IPv4zero) {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got zero IPv4 address", typeof.Name(), n, val.Kind())
|
||||
}
|
||||
} else {
|
||||
params.Set(name, ip.String())
|
||||
}
|
||||
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())
|
||||
}
|
||||
} else {
|
||||
params.Set(name, s)
|
||||
}
|
||||
default:
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), n, val.Kind())
|
||||
}
|
||||
} else {
|
||||
v := val.Bytes()
|
||||
params.Set(name, base64.StdEncoding.EncodeToString(v))
|
||||
}
|
||||
}
|
||||
case reflect.String:
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), n, val.Kind())
|
||||
}
|
||||
} else {
|
||||
elems := make([]string, 0, val.Len())
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
// XXX what if the value contains a comma? Double encode?
|
||||
s := val.Index(i).String()
|
||||
elems = append(elems, s)
|
||||
}
|
||||
params.Set(name, strings.Join(elems, ","))
|
||||
}
|
||||
default:
|
||||
switch field.Type.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())
|
||||
}
|
||||
} else {
|
||||
value := 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)
|
||||
if !ok {
|
||||
return fmt.Errorf("not a String, %T", v)
|
||||
}
|
||||
ss[i] = s.String()
|
||||
}
|
||||
params.Set(name, strings.Join(ss, ","))
|
||||
}
|
||||
default:
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return fmt.Errorf("%s.%s (%v) is required, got empty slice", typeof.Name(), n, val.Kind())
|
||||
}
|
||||
} else {
|
||||
err := prepareList(name, params, val.Interface())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
value, err = prepareBool(val.Bool(), required)
|
||||
|
||||
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())
|
||||
err = fmt.Errorf("field is required, got empty map")
|
||||
}
|
||||
} else {
|
||||
err := prepareMap(name, params, val.Interface())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value, err = prepareMap(name, val.Interface())
|
||||
}
|
||||
|
||||
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:
|
||||
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())
|
||||
}
|
||||
value, err = prepareStruct(val.Interface(), required)
|
||||
|
||||
default:
|
||||
if required {
|
||||
return fmt.Errorf("unsupported type %s.%s (%v)", typeof.Name(), n, val.Kind())
|
||||
err = fmt.Errorf("unsupported type")
|
||||
}
|
||||
fmt.Printf("%s\n", val.Kind())
|
||||
}
|
||||
} else {
|
||||
log.Printf("[SKIP] %s.%s no json label found", typeof.Name(), field.Name)
|
||||
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 nil
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func prepareList(prefix string, params url.Values, slice interface{}) error {
|
||||
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 nil, fmt.Errorf("field is required, got %q", v)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
func prepareBool(v bool, required bool) (*string, error) {
|
||||
value := strconv.FormatBool(v)
|
||||
if !v {
|
||||
if required {
|
||||
return &value, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
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++ {
|
||||
err := prepareValues(fmt.Sprintf("%s[%d].", prefix, i), params, value.Index(i).Interface())
|
||||
ps, err := prepareValues(fmt.Sprintf("%s[%d].", prefix, i), value.Index(i).Interface())
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, xs := range ps {
|
||||
for _, x := range xs {
|
||||
params.Add(k, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return params, nil
|
||||
}
|
||||
|
||||
func prepareMap(prefix string, params url.Values, m interface{}) error {
|
||||
value := reflect.ValueOf(m)
|
||||
func prepareMap(prefix string, m interface{}) (url.Values, error) {
|
||||
value := url.Values{}
|
||||
v := reflect.ValueOf(m)
|
||||
|
||||
for i, key := range value.MapKeys() {
|
||||
for i, key := range v.MapKeys() {
|
||||
var keyName string
|
||||
var keyValue string
|
||||
|
||||
@@ -295,19 +245,143 @@ func prepareMap(prefix string, params url.Values, m interface{}) error {
|
||||
case reflect.String:
|
||||
keyName = key.String()
|
||||
default:
|
||||
return fmt.Errorf("only map[string]string are supported (XXX)")
|
||||
return value, fmt.Errorf("only map[string]string are supported (XXX)")
|
||||
}
|
||||
|
||||
val := value.MapIndex(key)
|
||||
val := v.MapIndex(key)
|
||||
switch val.Kind() {
|
||||
case reflect.String:
|
||||
keyValue = val.String()
|
||||
default:
|
||||
return fmt.Errorf("only map[string]string are supported (XXX)")
|
||||
return value, fmt.Errorf("only map[string]string are supported (XXX)")
|
||||
}
|
||||
params.Set(fmt.Sprintf("%s[%d].%s", prefix, i, keyName), keyValue)
|
||||
|
||||
value.Set(fmt.Sprintf("%s[%d].%s", prefix, i, keyName), keyValue)
|
||||
}
|
||||
return nil
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func preparePtr(kind reflect.Kind, val reflect.Value, required bool) (*string, error) {
|
||||
if val.IsNil() {
|
||||
if required {
|
||||
return nil, fmt.Errorf("field is required, got empty ptr")
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case reflect.Bool:
|
||||
return prepareBool(val.Elem().Bool(), true)
|
||||
case reflect.Struct:
|
||||
return prepareStruct(val.Interface(), required)
|
||||
default:
|
||||
return nil, fmt.Errorf("kind %v is not supported as a ptr", kind)
|
||||
}
|
||||
}
|
||||
|
||||
func prepareSlice(name string, fieldType reflect.Type, val reflect.Value, required bool) (interface{}, error) {
|
||||
switch fieldType.Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
switch fieldType {
|
||||
case reflect.TypeOf(net.IPv4zero):
|
||||
ip := (net.IP)(val.Bytes())
|
||||
if ip == nil || ip.Equal(net.IP{}) {
|
||||
if required {
|
||||
return nil, fmt.Errorf("field is required, got zero IPv4 address")
|
||||
}
|
||||
} else {
|
||||
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 nil, fmt.Errorf("field is required, got empty MAC address")
|
||||
}
|
||||
} else {
|
||||
return &s, nil
|
||||
}
|
||||
default:
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return nil, fmt.Errorf("field is required, got empty slice")
|
||||
}
|
||||
} else {
|
||||
value := base64.StdEncoding.EncodeToString(val.Bytes())
|
||||
return &value, nil
|
||||
}
|
||||
}
|
||||
case reflect.String:
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return nil, fmt.Errorf("field is required, got empty slice")
|
||||
}
|
||||
} else {
|
||||
elems := make([]string, 0, val.Len())
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
// XXX what if the value contains a comma? Double encode?
|
||||
s := val.Index(i).String()
|
||||
elems = append(elems, s)
|
||||
}
|
||||
value := strings.Join(elems, ",")
|
||||
return &value, nil
|
||||
}
|
||||
default:
|
||||
switch fieldType.Elem() {
|
||||
case reflect.TypeOf(CIDR{}), reflect.TypeOf(UUID{}):
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return nil, fmt.Errorf("field is required, got empty slice")
|
||||
}
|
||||
} else {
|
||||
v := reflect.ValueOf(val.Interface())
|
||||
ss := make([]string, val.Len())
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
e := v.Index(i).Interface()
|
||||
s, ok := e.(fmt.Stringer)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("not a String, %T", e)
|
||||
}
|
||||
ss[i] = s.String()
|
||||
}
|
||||
value := strings.Join(ss, ",")
|
||||
return &value, nil
|
||||
}
|
||||
default:
|
||||
if val.Len() == 0 {
|
||||
if required {
|
||||
return nil, fmt.Errorf("field is required, got empty slice")
|
||||
}
|
||||
} else {
|
||||
return prepareList(name, val.Interface())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func prepareStruct(i interface{}, required bool) (*string, error) {
|
||||
s, ok := i.(fmt.Stringer)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("struct field not a Stringer")
|
||||
}
|
||||
|
||||
if s == nil {
|
||||
if required {
|
||||
return nil, fmt.Errorf("field is required, got %#v", s)
|
||||
}
|
||||
}
|
||||
|
||||
return prepareString(s.String(), required)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
80
vendor/github.com/exoscale/egoscale/snapshots.go
generated
vendored
80
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"`
|
||||
@@ -56,30 +53,43 @@ 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."`
|
||||
VolumeID *UUID `json:"volumeid" doc:"The ID of 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)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user