mirror of
https://github.com/containous/traefik.git
synced 2024-12-22 13:34:03 +03:00
ACME TLS ALPN
This commit is contained in:
parent
17ad5153b8
commit
139f280f35
26
Gopkg.lock
generated
26
Gopkg.lock
generated
@ -98,6 +98,12 @@
|
||||
revision = "a8b993ba6abdb0e0c12b0125c603323a71c7790c"
|
||||
source = "github.com/ijc25/Gotty"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/OpenDNS/vegadns2client"
|
||||
packages = ["."]
|
||||
revision = "a3fa4a771d87bda2514a90a157e1fed1b6897d2e"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/PuerkitoBio/purell"
|
||||
packages = ["."]
|
||||
@ -758,6 +764,7 @@
|
||||
version = "v1.3.7"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/jjcollinge/servicefabric"
|
||||
packages = ["."]
|
||||
revision = "8eebe170fa1ba25d3dfb928b3f86a7313b13b9fe"
|
||||
@ -1087,6 +1094,17 @@
|
||||
packages = ["."]
|
||||
revision = "256dc444b735e061061cf46c809487313d5b0065"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/sacloud/libsacloud"
|
||||
packages = [
|
||||
".",
|
||||
"api",
|
||||
"sacloud",
|
||||
"sacloud/ostype"
|
||||
]
|
||||
revision = "306ea89b6ef19334614f7b0fc5aa19595022bb8c"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/samuel/go-zookeeper"
|
||||
packages = ["zk"]
|
||||
@ -1257,6 +1275,7 @@
|
||||
packages = [
|
||||
"acme",
|
||||
"log",
|
||||
"platform/config/env",
|
||||
"providers/dns",
|
||||
"providers/dns/auroradns",
|
||||
"providers/dns/azure",
|
||||
@ -1281,6 +1300,7 @@
|
||||
"providers/dns/linode",
|
||||
"providers/dns/namecheap",
|
||||
"providers/dns/namedotcom",
|
||||
"providers/dns/nifcloud",
|
||||
"providers/dns/ns1",
|
||||
"providers/dns/otc",
|
||||
"providers/dns/ovh",
|
||||
@ -1288,9 +1308,11 @@
|
||||
"providers/dns/rackspace",
|
||||
"providers/dns/rfc2136",
|
||||
"providers/dns/route53",
|
||||
"providers/dns/sakuracloud",
|
||||
"providers/dns/vegadns",
|
||||
"providers/dns/vultr"
|
||||
]
|
||||
revision = "7fedfd1388f016c7ca7ed92a7f2024d06a7e20d8"
|
||||
revision = "e0d512138c43e3f056a41cd7a5beff662ec130d3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@ -1711,6 +1733,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "593c88b41d6384d68bd610a8c80c39017e77584f4e3454b2ca5c26ee904bf1da"
|
||||
inputs-digest = "53d03fd81596d9560d751bc1102615990a91b0779cff079784a9a1c6641bd503"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
@ -187,7 +187,7 @@ func (dc *DomainsCertificates) removeDuplicates() {
|
||||
}
|
||||
|
||||
func (dc *DomainsCertificates) removeEmpty() {
|
||||
certs := []*DomainsCertificate{}
|
||||
var certs []*DomainsCertificate
|
||||
for _, cert := range dc.Certs {
|
||||
if cert.Certificate != nil && len(cert.Certificate.Certificate) > 0 && len(cert.Certificate.PrivateKey) > 0 {
|
||||
certs = append(certs, cert)
|
||||
|
31
acme/acme.go
31
acme/acme.go
@ -51,6 +51,7 @@ type ACME struct {
|
||||
KeyType string `description:"KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'. Default to 'RSA4096'"`
|
||||
DNSChallenge *acmeprovider.DNSChallenge `description:"Activate DNS-01 Challenge"`
|
||||
HTTPChallenge *acmeprovider.HTTPChallenge `description:"Activate HTTP-01 Challenge"`
|
||||
TLSChallenge *acmeprovider.TLSChallenge `description:"Activate TLS-ALPN-01 Challenge"`
|
||||
DNSProvider string `description:"(Deprecated) Activate DNS-01 Challenge"` // Deprecated
|
||||
DelayDontCheckDNS flaeg.Duration `description:"(Deprecated) Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."` // Deprecated
|
||||
ACMELogging bool `description:"Enable debug logging of ACME actions."`
|
||||
@ -59,6 +60,7 @@ type ACME struct {
|
||||
defaultCertificate *tls.Certificate
|
||||
store cluster.Store
|
||||
challengeHTTPProvider *challengeHTTPProvider
|
||||
challengeTLSProvider *challengeTLSProvider
|
||||
checkOnDemandDomain func(domain string) bool
|
||||
jobs *channels.InfiniteChannel
|
||||
TLSConfig *tls.Config `description:"TLS config in case wildcard certs are used"`
|
||||
@ -69,7 +71,7 @@ func (a *ACME) init() error {
|
||||
acme.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
|
||||
|
||||
if a.ACMELogging {
|
||||
legolog.Logger = fmtlog.New(log.WriterLevel(logrus.DebugLevel), "legolog: ", 0)
|
||||
legolog.Logger = fmtlog.New(log.WriterLevel(logrus.InfoLevel), "legolog: ", 0)
|
||||
} else {
|
||||
legolog.Logger = fmtlog.New(ioutil.Discard, "", 0)
|
||||
}
|
||||
@ -122,11 +124,12 @@ func (a *ACME) CreateClusterConfig(leadership *cluster.Leadership, tlsConfig *tl
|
||||
}
|
||||
|
||||
if len(a.Storage) == 0 {
|
||||
return errors.New("Empty Store, please provide a key for certs storage")
|
||||
return errors.New("empty Store, please provide a key for certs storage")
|
||||
}
|
||||
|
||||
a.checkOnDemandDomain = checkOnDemandDomain
|
||||
a.dynamicCerts = certs
|
||||
a.challengeTLSProvider = &challengeTLSProvider{store: a.store}
|
||||
|
||||
tlsConfig.Certificates = append(tlsConfig.Certificates, *a.defaultCertificate)
|
||||
tlsConfig.GetCertificate = a.getCertificate
|
||||
@ -246,16 +249,23 @@ func (a *ACME) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificat
|
||||
return providedCertificate, nil
|
||||
}
|
||||
|
||||
if challengeCert, ok := a.challengeTLSProvider.getCertificate(domain); ok {
|
||||
log.Debugf("ACME got challenge %s", domain)
|
||||
return challengeCert, nil
|
||||
}
|
||||
|
||||
if domainCert, ok := account.DomainsCertificate.getCertificateForDomain(domain); ok {
|
||||
log.Debugf("ACME got domain cert %s", domain)
|
||||
return domainCert.tlsCert, nil
|
||||
}
|
||||
|
||||
if a.OnDemand {
|
||||
if a.checkOnDemandDomain != nil && !a.checkOnDemandDomain(domain) {
|
||||
return nil, nil
|
||||
}
|
||||
return a.loadCertificateOnDemand(clientHello)
|
||||
}
|
||||
|
||||
log.Debugf("No certificate found or generated for %s", domain)
|
||||
return nil, nil
|
||||
}
|
||||
@ -417,6 +427,7 @@ func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// DNS challenge
|
||||
if a.DNSChallenge != nil && len(a.DNSChallenge.Provider) > 0 {
|
||||
log.Debugf("Using DNS Challenge provider: %s", a.DNSChallenge.Provider)
|
||||
|
||||
@ -431,21 +442,30 @@ func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01})
|
||||
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.TLSALPN01})
|
||||
err = client.SetChallengeProvider(acme.DNS01, provider)
|
||||
return client, err
|
||||
}
|
||||
|
||||
// HTTP challenge
|
||||
if a.HTTPChallenge != nil && len(a.HTTPChallenge.EntryPoint) > 0 {
|
||||
log.Debug("Using HTTP Challenge provider.")
|
||||
|
||||
client.ExcludeChallenges([]acme.Challenge{acme.DNS01})
|
||||
client.ExcludeChallenges([]acme.Challenge{acme.DNS01, acme.TLSALPN01})
|
||||
a.challengeHTTPProvider = &challengeHTTPProvider{store: a.store}
|
||||
err = client.SetChallengeProvider(acme.HTTP01, a.challengeHTTPProvider)
|
||||
return client, err
|
||||
}
|
||||
|
||||
return nil, errors.New("ACME challenge not specified, please select HTTP or DNS Challenge")
|
||||
// TLS Challenge
|
||||
if a.TLSChallenge != nil {
|
||||
log.Debug("Using TLS Challenge provider.")
|
||||
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.DNS01})
|
||||
err = client.SetChallengeProvider(acme.TLSALPN01, a.challengeTLSProvider)
|
||||
return client, err
|
||||
}
|
||||
|
||||
return nil, errors.New("ACME challenge not specified, please select TLS or HTTP or DNS Challenge")
|
||||
}
|
||||
|
||||
func (a *ACME) loadCertificateOnDemand(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
@ -631,7 +651,6 @@ func (a *ACME) getDomainsCertificates(domains []string) (*Certificate, error) {
|
||||
|
||||
certificate, err := a.client.ObtainCertificate(domains, bundle, nil, OSCPMustStaple)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return nil, fmt.Errorf("cannot obtain certificates: %+v", err)
|
||||
}
|
||||
|
||||
|
127
acme/challenge_tls_provider.go
Normal file
127
acme/challenge_tls_provider.go
Normal file
@ -0,0 +1,127 @@
|
||||
package acme
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cenk/backoff"
|
||||
"github.com/containous/traefik/cluster"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/safe"
|
||||
"github.com/xenolf/lego/acme"
|
||||
)
|
||||
|
||||
var _ acme.ChallengeProviderTimeout = (*challengeTLSProvider)(nil)
|
||||
|
||||
type challengeTLSProvider struct {
|
||||
store cluster.Store
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
func (c *challengeTLSProvider) getCertificate(domain string) (cert *tls.Certificate, exists bool) {
|
||||
log.Debugf("Looking for an existing ACME challenge for %s...", domain)
|
||||
|
||||
if !strings.HasSuffix(domain, ".acme.invalid") {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
|
||||
account := c.store.Get().(*Account)
|
||||
if account.ChallengeCerts == nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
account.Init()
|
||||
|
||||
var result *tls.Certificate
|
||||
operation := func() error {
|
||||
for _, cert := range account.ChallengeCerts {
|
||||
for _, dns := range cert.certificate.Leaf.DNSNames {
|
||||
if domain == dns {
|
||||
result = cert.certificate
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("cannot find challenge cert for domain %s", domain)
|
||||
}
|
||||
|
||||
notify := func(err error, time time.Duration) {
|
||||
log.Errorf("Error getting cert: %v, retrying in %s", err, time)
|
||||
}
|
||||
ebo := backoff.NewExponentialBackOff()
|
||||
ebo.MaxElapsedTime = 60 * time.Second
|
||||
|
||||
err := backoff.RetryNotify(safe.OperationWithRecover(operation), ebo, notify)
|
||||
if err != nil {
|
||||
log.Errorf("Error getting cert: %v", err)
|
||||
return nil, false
|
||||
|
||||
}
|
||||
return result, true
|
||||
}
|
||||
|
||||
func (c *challengeTLSProvider) Present(domain, token, keyAuth string) error {
|
||||
log.Debugf("Challenge Present %s", domain)
|
||||
|
||||
cert, err := tlsALPN01ChallengeCert(domain, keyAuth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
transaction, object, err := c.store.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
account := object.(*Account)
|
||||
if account.ChallengeCerts == nil {
|
||||
account.ChallengeCerts = map[string]*ChallengeCert{}
|
||||
}
|
||||
account.ChallengeCerts[domain] = cert
|
||||
|
||||
return transaction.Commit(account)
|
||||
}
|
||||
|
||||
func (c *challengeTLSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||
log.Debugf("Challenge CleanUp %s", domain)
|
||||
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
transaction, object, err := c.store.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
account := object.(*Account)
|
||||
delete(account.ChallengeCerts, domain)
|
||||
|
||||
return transaction.Commit(account)
|
||||
}
|
||||
|
||||
func (c *challengeTLSProvider) Timeout() (timeout, interval time.Duration) {
|
||||
return 60 * time.Second, 5 * time.Second
|
||||
}
|
||||
|
||||
func tlsALPN01ChallengeCert(domain, keyAuth string) (*ChallengeCert, error) {
|
||||
tempCertPEM, rsaPrivPEM, err := acme.TLSALPNChallengeBlocks(domain, keyAuth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certificate, err := tls.X509KeyPair(tempCertPEM, rsaPrivPEM)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ChallengeCert{Certificate: tempCertPEM, PrivateKey: rsaPrivPEM, certificate: &certificate}, nil
|
||||
}
|
@ -200,6 +200,11 @@ func runCmd(globalConfiguration *configuration.GlobalConfiguration, configFile s
|
||||
internalRouter.AddRouter(acmeprovider)
|
||||
}
|
||||
|
||||
// TLS ALPN 01
|
||||
if acmeprovider.HTTPChallenge == nil && acmeprovider.DNSChallenge == nil && acmeprovider.TLSChallenge != nil {
|
||||
entryPoint.TLSALPNGetter = acmeprovider.GetTLSALPNCertificate
|
||||
}
|
||||
|
||||
if acmeprovider.EntryPoint == entryPointName && acmeprovider.OnDemand {
|
||||
entryPoint.OnDemandListener = acmeprovider.ListenRequest
|
||||
}
|
||||
|
@ -360,6 +360,16 @@ func (gc *GlobalConfiguration) initACMEProvider() {
|
||||
gc.ACME.HTTPChallenge = nil
|
||||
}
|
||||
|
||||
if gc.ACME.DNSChallenge != nil && gc.ACME.TLSChallenge != nil {
|
||||
log.Warn("Unable to use DNS challenge and TLS challenge at the same time. Fallback to DNS challenge.")
|
||||
gc.ACME.TLSChallenge = nil
|
||||
}
|
||||
|
||||
if gc.ACME.HTTPChallenge != nil && gc.ACME.TLSChallenge != nil {
|
||||
log.Warn("Unable to use HTTP challenge and TLS challenge at the same time. Fallback to TLS challenge.")
|
||||
gc.ACME.HTTPChallenge = nil
|
||||
}
|
||||
|
||||
// TODO: to remove in the future
|
||||
if len(gc.ACME.StorageFile) > 0 && len(gc.ACME.Storage) == 0 {
|
||||
log.Warn("ACME.StorageFile is deprecated, use ACME.Storage instead")
|
||||
@ -392,6 +402,7 @@ func (gc *GlobalConfiguration) InitACMEProvider() *acmeprovider.Provider {
|
||||
Storage: gc.ACME.Storage,
|
||||
HTTPChallenge: gc.ACME.HTTPChallenge,
|
||||
DNSChallenge: gc.ACME.DNSChallenge,
|
||||
TLSChallenge: gc.ACME.TLSChallenge,
|
||||
Domains: gc.ACME.Domains,
|
||||
ACMELogging: gc.ACME.ACMELogging,
|
||||
CAServer: gc.ACME.CAServer,
|
||||
@ -399,7 +410,7 @@ func (gc *GlobalConfiguration) InitACMEProvider() *acmeprovider.Provider {
|
||||
}
|
||||
|
||||
store := acmeprovider.NewLocalStore(provider.Storage)
|
||||
provider.Store = &store
|
||||
provider.Store = store
|
||||
acme.ConvertToNewFormat(provider.Storage)
|
||||
gc.ACME = nil
|
||||
return provider
|
||||
|
@ -162,7 +162,63 @@ caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
# ...
|
||||
```
|
||||
|
||||
### `dnsChallenge`
|
||||
### ACME Challenge
|
||||
|
||||
#### TLS Challenge
|
||||
|
||||
Use the `TLS-ALPN-01` challenge to generate and renew ACME certificates by provisioning a TLS certificate.
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
entryPoint = "https"
|
||||
[acme.tlsChallenge]
|
||||
```
|
||||
|
||||
#### `httpChallenge`
|
||||
|
||||
Use the `HTTP-01` challenge to generate and renew ACME certificates by provisioning a HTTP resource under a well-known URI.
|
||||
|
||||
Redirection is fully compatible with the `HTTP-01` challenge.
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
entryPoint = "https"
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "http"
|
||||
```
|
||||
|
||||
!!! note
|
||||
If the `HTTP-01` challenge is used, `acme.httpChallenge.entryPoint` has to be defined and reachable by Let's Encrypt through port 80.
|
||||
This is a Let's Encrypt limitation as described on the [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72).
|
||||
|
||||
##### `entryPoint`
|
||||
|
||||
Specify the entryPoint to use during the challenges.
|
||||
|
||||
```toml
|
||||
defaultEntryPoints = ["http", "https"]
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":80"
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
[entryPoints.https.tls]
|
||||
# ...
|
||||
|
||||
[acme]
|
||||
# ...
|
||||
entryPoint = "https"
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "http"
|
||||
```
|
||||
|
||||
!!! note
|
||||
`acme.httpChallenge.entryPoint` has to be reachable through port 80. It's a Let's Encrypt limitation as described on the [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72).
|
||||
|
||||
#### `dnsChallenge`
|
||||
|
||||
Use the `DNS-01` challenge to generate and renew ACME certificates by provisioning a DNS record.
|
||||
|
||||
@ -175,7 +231,7 @@ Use the `DNS-01` challenge to generate and renew ACME certificates by provisioni
|
||||
# ...
|
||||
```
|
||||
|
||||
#### `delayBeforeCheck`
|
||||
##### `delayBeforeCheck`
|
||||
|
||||
By default, the `provider` will verify the TXT DNS challenge record before letting ACME verify.
|
||||
If `delayBeforeCheck` is greater than zero, this check is delayed for the configured duration in seconds.
|
||||
@ -185,7 +241,7 @@ Useful if internal networks block external DNS queries.
|
||||
!!! note
|
||||
A `provider` is mandatory.
|
||||
|
||||
#### `provider`
|
||||
##### `provider`
|
||||
|
||||
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.
|
||||
|
||||
@ -215,6 +271,7 @@ Here is a list of supported `provider`s, that can automate the DNS verification,
|
||||
| manual | - | none, but you need to run Træfik interactively, turn on `acmeLogging` to see instructions and press <kbd>Enter</kbd>. | YES |
|
||||
| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | Not tested yet |
|
||||
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | 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/en/) | `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 |
|
||||
@ -222,8 +279,11 @@ Here is a list of supported `provider`s, that can automate the DNS verification,
|
||||
| [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 |
|
||||
| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | Not tested yet |
|
||||
| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | Not tested yet |
|
||||
|
||||
|
||||
### `domains`
|
||||
|
||||
You can provide SANs (alternative domains) to each main domain.
|
||||
@ -272,49 +332,6 @@ Eventhough this behaviour is [DNS RFC](https://community.letsencrypt.org/t/wildc
|
||||
The Træfik ACME client library [LEGO](https://github.com/xenolf/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.
|
||||
|
||||
### `httpChallenge`
|
||||
|
||||
Use the `HTTP-01` challenge to generate and renew ACME certificates by provisioning a HTTP resource under a well-known URI.
|
||||
|
||||
Redirection is fully compatible with the `HTTP-01` challenge.
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
entryPoint = "https"
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "http"
|
||||
```
|
||||
|
||||
!!! note
|
||||
If the `HTTP-01` challenge is used, `acme.httpChallenge.entryPoint` has to be defined and reachable by Let's Encrypt through port 80.
|
||||
This is a Let's Encrypt limitation as described on the [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72).
|
||||
|
||||
#### `entryPoint`
|
||||
|
||||
Specify the entryPoint to use during the challenges.
|
||||
|
||||
```toml
|
||||
defaultEntryPoints = ["http", "https"]
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":80"
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
[entryPoints.https.tls]
|
||||
# ...
|
||||
|
||||
[acme]
|
||||
# ...
|
||||
entryPoint = "https"
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "http"
|
||||
```
|
||||
|
||||
!!! note
|
||||
`acme.httpChallenge.entryPoint` has to be reachable through port 80. It's a Let's Encrypt limitation as described on the [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72).
|
||||
|
||||
### `onDemand` (Deprecated)
|
||||
|
||||
!!! danger "DEPRECATED"
|
||||
|
@ -4,8 +4,10 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/containous/traefik/integration/try"
|
||||
@ -13,267 +15,359 @@ import (
|
||||
"github.com/containous/traefik/testhelpers"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/go-check/check"
|
||||
"github.com/miekg/dns"
|
||||
checker "github.com/vdemeester/shakers"
|
||||
)
|
||||
|
||||
// ACME test suites (using libcompose)
|
||||
type AcmeSuite struct {
|
||||
BaseSuite
|
||||
boulderIP string
|
||||
pebbleIP string
|
||||
fakeDNSServer *dns.Server
|
||||
}
|
||||
|
||||
// Acme tests configuration
|
||||
type AcmeTestCase struct {
|
||||
configuration acme.Configuration
|
||||
type acmeTestCase struct {
|
||||
template templateModel
|
||||
traefikConfFilePath string
|
||||
expectedDomain string
|
||||
expectedCommonName string
|
||||
expectedAlgorithm x509.PublicKeyAlgorithm
|
||||
}
|
||||
|
||||
type templateModel struct {
|
||||
PortHTTP string
|
||||
PortHTTPS string
|
||||
Acme acme.Configuration
|
||||
}
|
||||
|
||||
const (
|
||||
// Domain to check
|
||||
acmeDomain = "traefik.acme.wtf"
|
||||
|
||||
// Wildcard domain to check
|
||||
wildcardDomain = "*.acme.wtf"
|
||||
|
||||
// Traefik default certificate
|
||||
traefikDefaultDomain = "TRAEFIK DEFAULT CERT"
|
||||
)
|
||||
|
||||
func (s *AcmeSuite) getAcmeURL() string {
|
||||
return fmt.Sprintf("http://%s:4001/directory", s.boulderIP)
|
||||
return fmt.Sprintf("https://%s:14000/dir", s.pebbleIP)
|
||||
}
|
||||
|
||||
func setupPebbleRootCA() (*http.Transport, error) {
|
||||
path, err := filepath.Abs("fixtures/acme/ssl/pebble.minica.pem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
os.Setenv("LEGO_CA_CERTIFICATES", path)
|
||||
os.Setenv("LEGO_CA_SERVER_NAME", "pebble")
|
||||
|
||||
customCAs, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certPool := x509.NewCertPool()
|
||||
if ok := certPool.AppendCertsFromPEM(customCAs); !ok {
|
||||
return nil, fmt.Errorf("error creating x509 cert pool from %q: %v", path, err)
|
||||
}
|
||||
|
||||
return &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
ServerName: "pebble",
|
||||
RootCAs: certPool,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *AcmeSuite) SetUpSuite(c *check.C) {
|
||||
s.createComposeProject(c, "boulder")
|
||||
s.createComposeProject(c, "peddle")
|
||||
s.composeProject.Start(c)
|
||||
|
||||
s.boulderIP = s.composeProject.Container(c, "boulder").NetworkSettings.IPAddress
|
||||
s.fakeDNSServer = startFakeDNSServer()
|
||||
|
||||
// wait for boulder
|
||||
err := try.GetRequest(s.getAcmeURL(), 120*time.Second, try.StatusCodeIs(http.StatusOK))
|
||||
s.pebbleIP = s.composeProject.Container(c, "pebble").NetworkSettings.IPAddress
|
||||
|
||||
pebbleTransport, err := setupPebbleRootCA()
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// wait for peddle
|
||||
req := testhelpers.MustNewRequest(http.MethodGet, s.getAcmeURL(), nil)
|
||||
|
||||
client := &http.Client{
|
||||
Transport: pebbleTransport,
|
||||
}
|
||||
|
||||
err = try.Do(5*time.Second, func() error {
|
||||
resp, errGet := client.Do(req)
|
||||
if errGet != nil {
|
||||
return errGet
|
||||
}
|
||||
return try.StatusCodeIs(http.StatusOK)(resp)
|
||||
})
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *AcmeSuite) TearDownSuite(c *check.C) {
|
||||
err := s.fakeDNSServer.Shutdown()
|
||||
if err != nil {
|
||||
c.Log(err)
|
||||
}
|
||||
|
||||
// shutdown and delete compose project
|
||||
if s.composeProject != nil {
|
||||
s.composeProject.Stop(c)
|
||||
}
|
||||
}
|
||||
|
||||
// Test ACME provider with certificate at start
|
||||
func (s *AcmeSuite) TestACMEProviderAtStart(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
func (s *AcmeSuite) TestHTTP01DomainsAtStart(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnHostRule: true,
|
||||
Domains: types.Domains{types.Domain{
|
||||
Main: "traefik.acme.wtf",
|
||||
}},
|
||||
},
|
||||
expectedDomain: acmeDomain,
|
||||
},
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test ACME provider with certificate at start
|
||||
func (s *AcmeSuite) TestACMEProviderAtStartInSAN(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
func (s *AcmeSuite) TestHTTP01DomainsInSANAtStart(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
Domains: types.Domains{types.Domain{
|
||||
Main: "acme.wtf",
|
||||
SANs: []string{"traefik.acme.wtf"},
|
||||
}},
|
||||
},
|
||||
expectedDomain: "acme.wtf",
|
||||
},
|
||||
expectedCommonName: "acme.wtf",
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test ACME provider with certificate at start
|
||||
func (s *AcmeSuite) TestACMEProviderOnHost(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
func (s *AcmeSuite) TestHTTP01OnHostRule(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
configuration: acme.Configuration{
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
CAServer: s.getAcmeURL(),
|
||||
OnHostRule: true,
|
||||
},
|
||||
expectedDomain: acmeDomain,
|
||||
},
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test ACME provider with certificate at start ECDSA algo
|
||||
func (s *AcmeSuite) TestACMEProviderOnHostECDSA(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
func (s *AcmeSuite) TestHTTP01OnHostRuleECDSA(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnHostRule: true,
|
||||
KeyType: "EC384",
|
||||
},
|
||||
expectedDomain: acmeDomain,
|
||||
},
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.ECDSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test ACME provider with certificate at start invalid algo default RSA
|
||||
func (s *AcmeSuite) TestACMEProviderOnHostInvalidAlgo(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
func (s *AcmeSuite) TestHTTP01OnHostRuleInvalidAlgo(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnHostRule: true,
|
||||
KeyType: "INVALID",
|
||||
},
|
||||
expectedDomain: acmeDomain,
|
||||
},
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test ACME provider with certificate at start and no ACME challenge
|
||||
func (s *AcmeSuite) TestACMEProviderOnHostWithNoACMEChallenge(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
func (s *AcmeSuite) TestHTTP01OnHostRuleWithPath(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_http01_web_path.toml",
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnHostRule: true,
|
||||
},
|
||||
expectedDomain: traefikDefaultDomain,
|
||||
},
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test OnDemand option with none provided certificate and challenge HTTP-01
|
||||
func (s *AcmeSuite) TestOnDemandRetrieveAcmeCertificateHTTP01(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
func (s *AcmeSuite) TestHTTP01OnHostRuleStaticCertificatesWithWildcard(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_tls.toml",
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnHostRule: true,
|
||||
},
|
||||
},
|
||||
expectedCommonName: wildcardDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
func (s *AcmeSuite) TestHTTP01OnHostRuleDynamicCertificatesWithWildcard(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_tls_dynamic.toml",
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnHostRule: true,
|
||||
},
|
||||
},
|
||||
expectedCommonName: wildcardDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
func (s *AcmeSuite) TestHTTP01OnDemand(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnDemand: true,
|
||||
},
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test OnHostRule option with none provided certificate and challenge HTTP-01
|
||||
func (s *AcmeSuite) TestOnHostRuleRetrieveAcmeCertificateHTTP01(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnHostRule: true,
|
||||
},
|
||||
expectedDomain: acmeDomain,
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test OnHostRule option with none provided certificate and challenge HTTP-01 and web path
|
||||
func (s *AcmeSuite) TestOnHostRuleRetrieveAcmeCertificateHTTP01WithPath(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_http01_web_path.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnHostRule: true,
|
||||
},
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test OnDemand option with a wildcard provided certificate
|
||||
func (s *AcmeSuite) TestOnDemandRetrieveAcmeCertificateWithWildcard(c *check.C) {
|
||||
func (s *AcmeSuite) TestHTTP01OnDemandStaticCertificatesWithWildcard(c *check.C) {
|
||||
// FIXME flaky
|
||||
c.Skip("Flaky behavior will be fixed in the next PR")
|
||||
testCase := AcmeTestCase{
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_tls.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnDemand: true,
|
||||
},
|
||||
expectedDomain: wildcardDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test onHostRule option with a wildcard provided certificate
|
||||
func (s *AcmeSuite) TestOnHostRuleRetrieveAcmeCertificateWithWildcard(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_tls.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnHostRule: true,
|
||||
},
|
||||
expectedDomain: wildcardDomain,
|
||||
expectedCommonName: wildcardDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test OnDemand option with a wildcard provided certificate
|
||||
func (s *AcmeSuite) TestOnDemandRetrieveAcmeCertificateWithDynamicWildcard(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
func (s *AcmeSuite) TestHTTP01OnDemandDynamicCertificatesWithWildcard(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_tls_dynamic.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnDemand: true,
|
||||
},
|
||||
expectedDomain: wildcardDomain,
|
||||
},
|
||||
expectedCommonName: wildcardDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
// Test onHostRule option with a wildcard provided certificate
|
||||
func (s *AcmeSuite) TestOnHostRuleRetrieveAcmeCertificateWithDynamicWildcard(c *check.C) {
|
||||
testCase := AcmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_tls_dynamic.toml",
|
||||
configuration: acme.Configuration{
|
||||
CAServer: s.getAcmeURL(),
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
func (s *AcmeSuite) TestTLSALPN01OnHostRule(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
TLSChallenge: &acme.TLSChallenge{},
|
||||
OnHostRule: true,
|
||||
},
|
||||
expectedDomain: wildcardDomain,
|
||||
},
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
func (s *AcmeSuite) TestTLSALPN01OnDemand(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
TLSChallenge: &acme.TLSChallenge{},
|
||||
OnDemand: true,
|
||||
},
|
||||
},
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
func (s *AcmeSuite) TestTLSALPN01DomainsAtStart(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
TLSChallenge: &acme.TLSChallenge{},
|
||||
Domains: types.Domains{types.Domain{
|
||||
Main: "traefik.acme.wtf",
|
||||
}},
|
||||
},
|
||||
},
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
s.retrieveAcmeCertificate(c, testCase)
|
||||
}
|
||||
|
||||
func (s *AcmeSuite) TestTLSALPN01DomainsInSANAtStart(c *check.C) {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme-base.toml",
|
||||
template: templateModel{
|
||||
Acme: acme.Configuration{
|
||||
TLSChallenge: &acme.TLSChallenge{},
|
||||
Domains: types.Domains{types.Domain{
|
||||
Main: "acme.wtf",
|
||||
SANs: []string{"traefik.acme.wtf"},
|
||||
}},
|
||||
},
|
||||
},
|
||||
expectedCommonName: "acme.wtf",
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}
|
||||
|
||||
@ -282,10 +376,12 @@ func (s *AcmeSuite) TestOnHostRuleRetrieveAcmeCertificateWithDynamicWildcard(c *
|
||||
|
||||
// Test Let's encrypt down
|
||||
func (s *AcmeSuite) TestNoValidLetsEncryptServer(c *check.C) {
|
||||
file := s.adaptFile(c, "fixtures/acme/acme-base.toml", acme.Configuration{
|
||||
file := s.adaptFile(c, "fixtures/acme/acme-base.toml", templateModel{
|
||||
Acme: acme.Configuration{
|
||||
CAServer: "http://wrongurl:4001/directory",
|
||||
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
|
||||
OnHostRule: true,
|
||||
},
|
||||
})
|
||||
defer os.Remove(file)
|
||||
|
||||
@ -301,8 +397,20 @@ func (s *AcmeSuite) TestNoValidLetsEncryptServer(c *check.C) {
|
||||
}
|
||||
|
||||
// Doing an HTTPS request and test the response certificate
|
||||
func (s *AcmeSuite) retrieveAcmeCertificate(c *check.C, testCase AcmeTestCase) {
|
||||
file := s.adaptFile(c, testCase.traefikConfFilePath, testCase.configuration)
|
||||
func (s *AcmeSuite) retrieveAcmeCertificate(c *check.C, testCase acmeTestCase) {
|
||||
if len(testCase.template.PortHTTP) == 0 {
|
||||
testCase.template.PortHTTP = ":5002"
|
||||
}
|
||||
|
||||
if len(testCase.template.PortHTTPS) == 0 {
|
||||
testCase.template.PortHTTPS = ":5001"
|
||||
}
|
||||
|
||||
if len(testCase.template.Acme.CAServer) == 0 {
|
||||
testCase.template.Acme.CAServer = s.getAcmeURL()
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, testCase.traefikConfFilePath, testCase.template)
|
||||
defer os.Remove(file)
|
||||
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
@ -357,8 +465,8 @@ func (s *AcmeSuite) retrieveAcmeCertificate(c *check.C, testCase AcmeTestCase) {
|
||||
}
|
||||
|
||||
cn := resp.TLS.PeerCertificates[0].Subject.CommonName
|
||||
if cn != testCase.expectedDomain {
|
||||
return fmt.Errorf("domain %s found instead of %s", cn, testCase.expectedDomain)
|
||||
if cn != testCase.expectedCommonName {
|
||||
return fmt.Errorf("domain %s found instead of %s", cn, testCase.expectedCommonName)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -367,6 +475,6 @@ func (s *AcmeSuite) retrieveAcmeCertificate(c *check.C, testCase AcmeTestCase) {
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(resp.StatusCode, checker.Equals, http.StatusOK)
|
||||
// Check Domain into response certificate
|
||||
c.Assert(resp.TLS.PeerCertificates[0].Subject.CommonName, checker.Equals, testCase.expectedDomain)
|
||||
c.Assert(resp.TLS.PeerCertificates[0].Subject.CommonName, checker.Equals, testCase.expectedCommonName)
|
||||
c.Assert(resp.TLS.PeerCertificates[0].PublicKeyAlgorithm, checker.Equals, testCase.expectedAlgorithm)
|
||||
}
|
||||
|
114
integration/fake_dns_server.go
Normal file
114
integration/fake_dns_server.go
Normal file
@ -0,0 +1,114 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
type handler struct{}
|
||||
|
||||
// ServeDNS a fake DNS server
|
||||
// Simplified version of the Challenge Test Server from Boulder
|
||||
// https://github.com/letsencrypt/boulder/blob/a6597b9f120207eff192c3e4107a7e49972a0250/test/challtestsrv/dnsone.go#L40
|
||||
func (s *handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
|
||||
m := new(dns.Msg)
|
||||
m.SetReply(r)
|
||||
m.Compress = false
|
||||
|
||||
fakeDNS := os.Getenv("DOCKER_HOST_IP")
|
||||
if fakeDNS == "" {
|
||||
fakeDNS = "127.0.0.1"
|
||||
}
|
||||
for _, q := range r.Question {
|
||||
log.Printf("Query -- [%s] %s", q.Name, dns.TypeToString[q.Qtype])
|
||||
|
||||
switch q.Qtype {
|
||||
case dns.TypeA:
|
||||
record := new(dns.A)
|
||||
record.Hdr = dns.RR_Header{
|
||||
Name: q.Name,
|
||||
Rrtype: dns.TypeA,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: 0,
|
||||
}
|
||||
record.A = net.ParseIP(fakeDNS)
|
||||
|
||||
m.Answer = append(m.Answer, record)
|
||||
case dns.TypeCAA:
|
||||
addCAARecord := true
|
||||
|
||||
var value string
|
||||
switch q.Name {
|
||||
case "bad-caa-reserved.com.":
|
||||
value = "sad-hacker-ca.invalid"
|
||||
case "good-caa-reserved.com.":
|
||||
value = "happy-hacker-ca.invalid"
|
||||
case "accounturi.good-caa-reserved.com.":
|
||||
uri := os.Getenv("ACCOUNT_URI")
|
||||
value = fmt.Sprintf("happy-hacker-ca.invalid; accounturi=%s", uri)
|
||||
case "recheck.good-caa-reserved.com.":
|
||||
// Allow issuance when we're running in the past
|
||||
// (under FAKECLOCK), otherwise deny issuance.
|
||||
if os.Getenv("FAKECLOCK") != "" {
|
||||
value = "happy-hacker-ca.invalid"
|
||||
} else {
|
||||
value = "sad-hacker-ca.invalid"
|
||||
}
|
||||
case "dns-01-only.good-caa-reserved.com.":
|
||||
value = "happy-hacker-ca.invalid; validationmethods=dns-01"
|
||||
case "http-01-only.good-caa-reserved.com.":
|
||||
value = "happy-hacker-ca.invalid; validationmethods=http-01"
|
||||
case "dns-01-or-http-01.good-caa-reserved.com.":
|
||||
value = "happy-hacker-ca.invalid; validationmethods=dns-01,http-01"
|
||||
default:
|
||||
addCAARecord = false
|
||||
}
|
||||
if addCAARecord {
|
||||
record := new(dns.CAA)
|
||||
record.Hdr = dns.RR_Header{
|
||||
Name: q.Name,
|
||||
Rrtype: dns.TypeCAA,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: 0,
|
||||
}
|
||||
record.Tag = "issue"
|
||||
record.Value = value
|
||||
m.Answer = append(m.Answer, record)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auth := new(dns.SOA)
|
||||
auth.Hdr = dns.RR_Header{Name: "boulder.invalid.", Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: 0}
|
||||
auth.Ns = "ns.boulder.invalid."
|
||||
auth.Mbox = "master.boulder.invalid."
|
||||
auth.Serial = 1
|
||||
auth.Refresh = 1
|
||||
auth.Retry = 1
|
||||
auth.Expire = 1
|
||||
auth.Minttl = 1
|
||||
m.Ns = append(m.Ns, auth)
|
||||
|
||||
w.WriteMsg(m)
|
||||
}
|
||||
|
||||
func startFakeDNSServer() *dns.Server {
|
||||
srv := &dns.Server{
|
||||
Addr: ":5053",
|
||||
Net: "udp",
|
||||
Handler: &handler{},
|
||||
}
|
||||
|
||||
go func() {
|
||||
log.Infof("Start a fake DNS server.")
|
||||
if err := srv.ListenAndServe(); err != nil {
|
||||
log.Fatalf("Failed to set udp listener %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return srv
|
||||
}
|
@ -4,9 +4,9 @@ defaultEntryPoints = ["http", "https"]
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":5002"
|
||||
address = "{{ .PortHTTP }}"
|
||||
[entryPoints.https]
|
||||
address = ":5001"
|
||||
address = "{{ .PortHTTPS }}"
|
||||
[entryPoints.https.tls]
|
||||
|
||||
[acme]
|
||||
@ -14,17 +14,21 @@ defaultEntryPoints = ["http", "https"]
|
||||
storage = "/tmp/acme.json"
|
||||
entryPoint = "https"
|
||||
acmeLogging = true
|
||||
onDemand = {{ .OnDemand }}
|
||||
onHostRule = {{ .OnHostRule }}
|
||||
keyType = "{{ .KeyType }}"
|
||||
caServer = "{{ .CAServer }}"
|
||||
onDemand = {{ .Acme.OnDemand }}
|
||||
onHostRule = {{ .Acme.OnHostRule }}
|
||||
keyType = "{{ .Acme.KeyType }}"
|
||||
caServer = "{{ .Acme.CAServer }}"
|
||||
|
||||
{{if .HTTPChallenge }}
|
||||
{{if .Acme.HTTPChallenge }}
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "{{ .HTTPChallenge.EntryPoint }}"
|
||||
entryPoint = "{{ .Acme.HTTPChallenge.EntryPoint }}"
|
||||
{{end}}
|
||||
|
||||
{{range .Domains}}
|
||||
{{if .Acme.TLSChallenge }}
|
||||
[acme.tlsChallenge]
|
||||
{{end}}
|
||||
|
||||
{{range .Acme.Domains}}
|
||||
[[acme.domains]]
|
||||
main = "{{ .Main }}"
|
||||
sans = [{{range .SANs }}
|
||||
|
@ -4,9 +4,9 @@ defaultEntryPoints = ["http", "https"]
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":5002"
|
||||
address = "{{ .PortHTTP }}"
|
||||
[entryPoints.https]
|
||||
address = ":5001"
|
||||
address = "{{ .PortHTTPS }}"
|
||||
[entryPoints.https.tls]
|
||||
|
||||
[acme]
|
||||
@ -14,17 +14,17 @@ defaultEntryPoints = ["http", "https"]
|
||||
storage = "/tmp/acme.json"
|
||||
entryPoint = "https"
|
||||
acmeLogging = true
|
||||
onDemand = {{ .OnDemand }}
|
||||
onHostRule = {{ .OnHostRule }}
|
||||
keyType = "{{ .KeyType }}"
|
||||
caServer = "{{ .CAServer }}"
|
||||
onDemand = {{ .Acme.OnDemand }}
|
||||
onHostRule = {{ .Acme.OnHostRule }}
|
||||
keyType = "{{ .Acme.KeyType }}"
|
||||
caServer = "{{ .Acme.CAServer }}"
|
||||
|
||||
{{if .HTTPChallenge }}
|
||||
{{if .Acme.HTTPChallenge }}
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "{{ .HTTPChallenge.EntryPoint }}"
|
||||
entryPoint = "{{ .Acme.HTTPChallenge.EntryPoint }}"
|
||||
{{end}}
|
||||
|
||||
{{range .Domains}}
|
||||
{{range .Acme.Domains}}
|
||||
[[acme.domains]]
|
||||
main = "{{ .Main }}"
|
||||
sans = [{{range .SANs }}
|
||||
|
@ -4,9 +4,9 @@ defaultEntryPoints = ["http", "https"]
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":5002"
|
||||
address = "{{ .PortHTTP }}"
|
||||
[entryPoints.https]
|
||||
address = ":5001"
|
||||
address = "{{ .PortHTTPS }}"
|
||||
[entryPoints.https.tls]
|
||||
[[entryPoints.https.tls.certificates]]
|
||||
certFile = "fixtures/acme/ssl/wildcard.crt"
|
||||
@ -17,17 +17,17 @@ defaultEntryPoints = ["http", "https"]
|
||||
storage = "/tmp/acme.json"
|
||||
entryPoint = "https"
|
||||
acmeLogging = true
|
||||
onDemand = {{ .OnDemand }}
|
||||
onHostRule = {{ .OnHostRule }}
|
||||
keyType = "{{ .KeyType }}"
|
||||
caServer = "{{ .CAServer }}"
|
||||
onDemand = {{ .Acme.OnDemand }}
|
||||
onHostRule = {{ .Acme.OnHostRule }}
|
||||
keyType = "{{ .Acme.KeyType }}"
|
||||
caServer = "{{ .Acme.CAServer }}"
|
||||
|
||||
{{if .HTTPChallenge }}
|
||||
{{if .Acme.HTTPChallenge }}
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "{{ .HTTPChallenge.EntryPoint }}"
|
||||
entryPoint = "{{ .Acme.HTTPChallenge.EntryPoint }}"
|
||||
{{end}}
|
||||
|
||||
{{range .Domains}}
|
||||
{{range .Acme.Domains}}
|
||||
[[acme.domains]]
|
||||
main = "{{ .Main }}"
|
||||
sans = [{{range .SANs }}
|
||||
|
@ -4,28 +4,27 @@ defaultEntryPoints = ["http", "https"]
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":5002"
|
||||
address = "{{ .PortHTTP }}"
|
||||
[entryPoints.https]
|
||||
address = ":5001"
|
||||
address = "{{ .PortHTTPS }}"
|
||||
[entryPoints.https.tls]
|
||||
|
||||
|
||||
[acme]
|
||||
email = "test@traefik.io"
|
||||
storage = "/tmp/acme.json"
|
||||
entryPoint = "https"
|
||||
acmeLogging = true
|
||||
onDemand = {{ .OnDemand }}
|
||||
onHostRule = {{ .OnHostRule }}
|
||||
keyType = "{{ .KeyType }}"
|
||||
caServer = "{{ .CAServer }}"
|
||||
onDemand = {{ .Acme.OnDemand }}
|
||||
onHostRule = {{ .Acme.OnHostRule }}
|
||||
keyType = "{{ .Acme.KeyType }}"
|
||||
caServer = "{{ .Acme.CAServer }}"
|
||||
|
||||
{{if .HTTPChallenge }}
|
||||
{{if .Acme.HTTPChallenge }}
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "{{ .HTTPChallenge.EntryPoint }}"
|
||||
entryPoint = "{{ .Acme.HTTPChallenge.EntryPoint }}"
|
||||
{{end}}
|
||||
|
||||
{{range .Domains}}
|
||||
{{range .Acme.Domains}}
|
||||
[[acme.domains]]
|
||||
main = "{{ .Main }}"
|
||||
sans = [{{range .SANs }}
|
||||
|
19
integration/fixtures/acme/ssl/pebble.minica.pem
Normal file
19
integration/fixtures/acme/ssl/pebble.minica.pem
Normal file
@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDCTCCAfGgAwIBAgIIJOLbes8sTr4wDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
|
||||
AxMVbWluaWNhIHJvb3QgY2EgMjRlMmRiMCAXDTE3MTIwNjE5NDIxMFoYDzIxMTcx
|
||||
MjA2MTk0MjEwWjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAyNGUyZGIwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5WgZNoVJandj43kkLyU50vzCZ
|
||||
alozvdRo3OFiKoDtmqKPNWRNO2hC9AUNxTDJco51Yc42u/WV3fPbbhSznTiOOVtn
|
||||
Ajm6iq4I5nZYltGGZetGDOQWr78y2gWY+SG078MuOO2hyDIiKtVc3xiXYA+8Hluu
|
||||
9F8KbqSS1h55yxZ9b87eKR+B0zu2ahzBCIHKmKWgc6N13l7aDxxY3D6uq8gtJRU0
|
||||
toumyLbdzGcupVvjbjDP11nl07RESDWBLG1/g3ktJvqIa4BWgU2HMh4rND6y8OD3
|
||||
Hy3H8MY6CElL+MOCbFJjWqhtOxeFyZZV9q3kYnk9CAuQJKMEGuN4GU6tzhW1AgMB
|
||||
AAGjRTBDMA4GA1UdDwEB/wQEAwIChDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB
|
||||
BQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0BAQsFAAOCAQEAF85v
|
||||
d40HK1ouDAtWeO1PbnWfGEmC5Xa478s9ddOd9Clvp2McYzNlAFfM7kdcj6xeiNhF
|
||||
WPIfaGAi/QdURSL/6C1KsVDqlFBlTs9zYfh2g0UXGvJtj1maeih7zxFLvet+fqll
|
||||
xseM4P9EVJaQxwuK/F78YBt0tCNfivC6JNZMgxKF59h0FBpH70ytUSHXdz7FKwix
|
||||
Mfn3qEb9BXSk0Q3prNV5sOV3vgjEtB4THfDxSz9z3+DepVnW3vbbqwEbkXdk3j82
|
||||
2muVldgOUgTwK8eT+XdofVdntzU/kzygSAtAQwLJfn51fS1GvEcYGBc1bDryIqmF
|
||||
p9BI7gVKtWSZYegicA==
|
||||
-----END CERTIFICATE-----
|
@ -1,49 +0,0 @@
|
||||
boulder:
|
||||
image: containous/boulder:containous-acmev2
|
||||
environment:
|
||||
FAKE_DNS: ${DOCKER_HOST_IP}
|
||||
PKCS11_PROXY_SOCKET: tcp://boulder-hsm:5657
|
||||
extra_hosts:
|
||||
- le.wtf:127.0.0.1
|
||||
- boulder:127.0.0.1
|
||||
ports:
|
||||
- 4000:4000 # ACME
|
||||
- 4001:4001 # ACMEv2
|
||||
- 4002:4002 # OCSP
|
||||
- 4003:4003 # OCSP
|
||||
- 4430:4430 # ACME via HTTPS
|
||||
- 4431:4431 # ACMEv2 via HTTPS
|
||||
- 4500:4500 # ct-test-srv
|
||||
- 6000:6000 # gsb-test-srv
|
||||
- 8000:8000 # debug ports
|
||||
- 8001:8001
|
||||
- 8002:8002
|
||||
- 8003:8003
|
||||
- 8004:8004
|
||||
- 8005:8005
|
||||
- 8006:8006
|
||||
- 8008:8008
|
||||
- 8009:8009
|
||||
- 8010:8010
|
||||
- 8055:8055 # dns-test-srv updates
|
||||
- 9380:9380 # mail-test-srv
|
||||
- 9381:9381 # mail-test-srv
|
||||
links:
|
||||
- bhsm:boulder-hsm
|
||||
- bmysql:boulder-mysql
|
||||
|
||||
bhsm:
|
||||
# To minimize the fetching of various layers this should match
|
||||
# the FROM image and tag in boulder/Dockerfile
|
||||
image: letsencrypt/boulder-tools:2018-03-07
|
||||
environment:
|
||||
PKCS11_DAEMON_SOCKET: tcp://0.0.0.0:5657
|
||||
command: /usr/local/bin/pkcs11-daemon /usr/lib/softhsm/libsofthsm2.so
|
||||
expose:
|
||||
- 5657
|
||||
bmysql:
|
||||
image: mariadb:10.1
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
|
||||
command: mysqld --bind-address=0.0.0.0
|
||||
log_driver: none
|
10
integration/resources/compose/peddle.yml
Normal file
10
integration/resources/compose/peddle.yml
Normal file
@ -0,0 +1,10 @@
|
||||
pebble:
|
||||
image: ldez/pebble
|
||||
command: --dnsserver ${DOCKER_HOST_IP}:5053
|
||||
ports:
|
||||
- 14000:14000
|
||||
environment:
|
||||
# https://github.com/letsencrypt/pebble#testing-at-full-speed
|
||||
- PEBBLE_VA_NOSLEEP=1
|
||||
# https://github.com/letsencrypt/pebble#invalid-anti-replay-nonce-errors
|
||||
- PEBBLE_WFE_NONCEREJECT=0
|
@ -73,8 +73,11 @@ func GetKeyType(value string) acme.KeyType {
|
||||
return acme.RSA4096
|
||||
case "RSA8192":
|
||||
return acme.RSA8192
|
||||
case "":
|
||||
log.Infof("The key type is empty. Use default key type %v.", acme.RSA4096)
|
||||
return acme.RSA4096
|
||||
default:
|
||||
log.Warnf("Unable to determine key type value %s. Use %s as default value", value, acme.RSA4096)
|
||||
log.Infof("Unable to determine key type value %q. Use default key type %v.", value, acme.RSA4096)
|
||||
return acme.RSA4096
|
||||
}
|
||||
}
|
||||
|
@ -2,43 +2,80 @@ package acme
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/cenk/backoff"
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/mux"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/safe"
|
||||
"github.com/xenolf/lego/acme"
|
||||
)
|
||||
|
||||
func dnsOverrideDelay(delay flaeg.Duration) error {
|
||||
if delay == 0 {
|
||||
return nil
|
||||
var _ acme.ChallengeProviderTimeout = (*challengeHTTP)(nil)
|
||||
|
||||
type challengeHTTP struct {
|
||||
Store Store
|
||||
}
|
||||
|
||||
// Present presents a challenge to obtain new ACME certificate
|
||||
func (c *challengeHTTP) Present(domain, token, keyAuth string) error {
|
||||
httpChallenges, err := c.Store.GetHTTPChallenges()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get HTTPChallenges : %s", err)
|
||||
}
|
||||
|
||||
if delay > 0 {
|
||||
log.Debugf("Delaying %d rather than validating DNS propagation now.", delay)
|
||||
|
||||
acme.PreCheckDNS = func(_, _ string) (bool, error) {
|
||||
time.Sleep(time.Duration(delay))
|
||||
return true, nil
|
||||
if httpChallenges == nil {
|
||||
httpChallenges = map[string]map[string][]byte{}
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("delayBeforeCheck: %d cannot be less than 0", delay)
|
||||
|
||||
if _, ok := httpChallenges[token]; !ok {
|
||||
httpChallenges[token] = map[string][]byte{}
|
||||
}
|
||||
|
||||
httpChallenges[token][domain] = []byte(keyAuth)
|
||||
|
||||
return c.Store.SaveHTTPChallenges(httpChallenges)
|
||||
}
|
||||
|
||||
// CleanUp cleans the challenges when certificate is obtained
|
||||
func (c *challengeHTTP) CleanUp(domain, token, keyAuth string) error {
|
||||
httpChallenges, err := c.Store.GetHTTPChallenges()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get HTTPChallenges : %s", err)
|
||||
}
|
||||
|
||||
log.Debugf("Challenge CleanUp for domain %s", domain)
|
||||
|
||||
if _, ok := httpChallenges[token]; ok {
|
||||
if _, domainOk := httpChallenges[token][domain]; domainOk {
|
||||
delete(httpChallenges[token], domain)
|
||||
}
|
||||
if len(httpChallenges[token]) == 0 {
|
||||
delete(httpChallenges, token)
|
||||
}
|
||||
return c.Store.SaveHTTPChallenges(httpChallenges)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Timeout calculates the maximum of time allowed to resolved an ACME challenge
|
||||
func (c *challengeHTTP) Timeout() (timeout, interval time.Duration) {
|
||||
return 60 * time.Second, 5 * time.Second
|
||||
}
|
||||
|
||||
func getTokenValue(token, domain string, store Store) []byte {
|
||||
log.Debugf("Looking for an existing ACME challenge for token %v...", token)
|
||||
var result []byte
|
||||
|
||||
operation := func() error {
|
||||
var ok bool
|
||||
httpChallenges, err := store.GetHTTPChallenges()
|
||||
if err != nil {
|
||||
return fmt.Errorf("HTTPChallenges not available : %s", err)
|
||||
}
|
||||
|
||||
var ok bool
|
||||
if result, ok = httpChallenges[token][domain]; !ok {
|
||||
return fmt.Errorf("cannot find challenge for token %v", token)
|
||||
}
|
||||
@ -56,44 +93,33 @@ func getTokenValue(token, domain string, store Store) []byte {
|
||||
log.Errorf("Error getting challenge for token: %v", err)
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func presentHTTPChallenge(domain, token, keyAuth string, store Store) error {
|
||||
httpChallenges, err := store.GetHTTPChallenges()
|
||||
// AddRoutes add routes on internal router
|
||||
func (p *Provider) AddRoutes(router *mux.Router) {
|
||||
router.Methods(http.MethodGet).
|
||||
Path(acme.HTTP01ChallengePath("{token}")).
|
||||
Handler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
vars := mux.Vars(req)
|
||||
if token, ok := vars["token"]; ok {
|
||||
domain, _, err := net.SplitHostPort(req.Host)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get HTTPChallenges : %s", err)
|
||||
log.Debugf("Unable to split host and port: %v. Fallback to request host.", err)
|
||||
domain = req.Host
|
||||
}
|
||||
|
||||
if httpChallenges == nil {
|
||||
httpChallenges = map[string]map[string][]byte{}
|
||||
}
|
||||
|
||||
if _, ok := httpChallenges[token]; !ok {
|
||||
httpChallenges[token] = map[string][]byte{}
|
||||
}
|
||||
|
||||
httpChallenges[token][domain] = []byte(keyAuth)
|
||||
|
||||
return store.SaveHTTPChallenges(httpChallenges)
|
||||
}
|
||||
|
||||
func cleanUpHTTPChallenge(domain, token string, store Store) error {
|
||||
httpChallenges, err := store.GetHTTPChallenges()
|
||||
tokenValue := getTokenValue(token, domain, p.Store)
|
||||
if len(tokenValue) > 0 {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
_, err = rw.Write(tokenValue)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get HTTPChallenges : %s", err)
|
||||
log.Errorf("Unable to write token : %v", err)
|
||||
}
|
||||
|
||||
log.Debugf("Challenge CleanUp for domain %s", domain)
|
||||
|
||||
if _, ok := httpChallenges[token]; ok {
|
||||
if _, domainOk := httpChallenges[token][domain]; domainOk {
|
||||
delete(httpChallenges[token], domain)
|
||||
return
|
||||
}
|
||||
if len(httpChallenges[token]) == 0 {
|
||||
delete(httpChallenges, token)
|
||||
}
|
||||
return store.SaveHTTPChallenges(httpChallenges)
|
||||
}
|
||||
return nil
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
}))
|
||||
}
|
52
provider/acme/challenge_tls.go
Normal file
52
provider/acme/challenge_tls.go
Normal file
@ -0,0 +1,52 @@
|
||||
package acme
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/xenolf/lego/acme"
|
||||
)
|
||||
|
||||
var _ acme.ChallengeProvider = (*challengeTLSALPN)(nil)
|
||||
|
||||
type challengeTLSALPN struct {
|
||||
Store Store
|
||||
}
|
||||
|
||||
func (c *challengeTLSALPN) Present(domain, token, keyAuth string) error {
|
||||
log.Debugf("TLS Challenge Present temp certificate for %s", domain)
|
||||
|
||||
certPEMBlock, keyPEMBlock, err := acme.TLSALPNChallengeBlocks(domain, keyAuth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cert := &Certificate{Certificate: certPEMBlock, Key: keyPEMBlock, Domain: types.Domain{Main: "TEMP-" + domain}}
|
||||
return c.Store.AddTLSChallenge(domain, cert)
|
||||
}
|
||||
|
||||
func (c *challengeTLSALPN) CleanUp(domain, token, keyAuth string) error {
|
||||
log.Debugf("TLS Challenge CleanUp temp certificate for %s", domain)
|
||||
|
||||
return c.Store.RemoveTLSChallenge(domain)
|
||||
}
|
||||
|
||||
// GetTLSALPNCertificate Get the temp certificate for ACME TLS-ALPN-O1 challenge.
|
||||
func (p *Provider) GetTLSALPNCertificate(domain string) (*tls.Certificate, error) {
|
||||
cert, err := p.Store.GetTLSChallenge(domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cert == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
certificate, err := tls.X509KeyPair(cert.Certificate, cert.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &certificate, nil
|
||||
}
|
@ -5,6 +5,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/safe"
|
||||
@ -17,18 +18,22 @@ type LocalStore struct {
|
||||
filename string
|
||||
storedData *StoredData
|
||||
SaveDataChan chan *StoredData `json:"-"`
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
// NewLocalStore initializes a new LocalStore with a file name
|
||||
func NewLocalStore(filename string) LocalStore {
|
||||
store := LocalStore{filename: filename, SaveDataChan: make(chan *StoredData)}
|
||||
func NewLocalStore(filename string) *LocalStore {
|
||||
store := &LocalStore{filename: filename, SaveDataChan: make(chan *StoredData)}
|
||||
store.listenSaveAction()
|
||||
return store
|
||||
}
|
||||
|
||||
func (s *LocalStore) get() (*StoredData, error) {
|
||||
if s.storedData == nil {
|
||||
s.storedData = &StoredData{HTTPChallenges: make(map[string]map[string][]byte)}
|
||||
s.storedData = &StoredData{
|
||||
HTTPChallenges: make(map[string]map[string][]byte),
|
||||
TLSChallenges: make(map[string]*Certificate),
|
||||
}
|
||||
|
||||
hasData, err := CheckFile(s.filename)
|
||||
if err != nil {
|
||||
@ -159,3 +164,41 @@ func (s *LocalStore) SaveHTTPChallenges(httpChallenges map[string]map[string][]b
|
||||
s.storedData.HTTPChallenges = httpChallenges
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddTLSChallenge Add a certificate to the ACME TLS-ALPN-01 certificates storage
|
||||
func (s *LocalStore) AddTLSChallenge(domain string, cert *Certificate) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if s.storedData.TLSChallenges == nil {
|
||||
s.storedData.TLSChallenges = make(map[string]*Certificate)
|
||||
}
|
||||
|
||||
s.storedData.TLSChallenges[domain] = cert
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTLSChallenge Get a certificate from the ACME TLS-ALPN-01 certificates storage
|
||||
func (s *LocalStore) GetTLSChallenge(domain string) (*Certificate, error) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if s.storedData.TLSChallenges == nil {
|
||||
s.storedData.TLSChallenges = make(map[string]*Certificate)
|
||||
}
|
||||
|
||||
return s.storedData.TLSChallenges[domain], nil
|
||||
}
|
||||
|
||||
// RemoveTLSChallenge Remove a certificate from the ACME TLS-ALPN-01 certificates storage
|
||||
func (s *LocalStore) RemoveTLSChallenge(domain string) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if s.storedData.TLSChallenges == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
delete(s.storedData.TLSChallenges, domain)
|
||||
return nil
|
||||
}
|
||||
|
@ -6,8 +6,6 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
fmtlog "log"
|
||||
"net"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -15,7 +13,6 @@ import (
|
||||
|
||||
"github.com/BurntSushi/ty/fun"
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/mux"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/rules"
|
||||
"github.com/containous/traefik/safe"
|
||||
@ -46,6 +43,7 @@ type Configuration struct {
|
||||
OnDemand bool `description:"Enable on demand certificate generation. This will request a certificate from Let's Encrypt during the first TLS handshake for a hostname that does not yet have a certificate."` // Deprecated
|
||||
DNSChallenge *DNSChallenge `description:"Activate DNS-01 Challenge"`
|
||||
HTTPChallenge *HTTPChallenge `description:"Activate HTTP-01 Challenge"`
|
||||
TLSChallenge *TLSChallenge `description:"Activate TLS-ALPN-01 Challenge"`
|
||||
Domains []types.Domain `description:"CN and SANs (alternative domains) to each main domain using format: --acme.domains='main.com,san1.com,san2.com' --acme.domains='*.main.net'. No SANs for wildcards domain. Wildcard domains only accepted with DNSChallenge"`
|
||||
}
|
||||
|
||||
@ -82,55 +80,17 @@ type HTTPChallenge struct {
|
||||
EntryPoint string `description:"HTTP challenge EntryPoint"`
|
||||
}
|
||||
|
||||
// TLSChallenge contains TLS challenge Configuration
|
||||
type TLSChallenge struct{}
|
||||
|
||||
// SetConfigListenerChan initializes the configFromListenerChan
|
||||
func (p *Provider) SetConfigListenerChan(configFromListenerChan chan types.Configuration) {
|
||||
p.configFromListenerChan = configFromListenerChan
|
||||
}
|
||||
|
||||
func (p *Provider) init() error {
|
||||
acme.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
|
||||
if p.ACMELogging {
|
||||
legolog.Logger = fmtlog.New(log.WriterLevel(logrus.DebugLevel), "legolog: ", 0)
|
||||
} else {
|
||||
legolog.Logger = fmtlog.New(ioutil.Discard, "", 0)
|
||||
}
|
||||
|
||||
var err error
|
||||
if p.Store == nil {
|
||||
err = errors.New("no store found for the ACME provider")
|
||||
return err
|
||||
}
|
||||
|
||||
p.account, err = p.Store.GetAccount()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get ACME account : %v", err)
|
||||
}
|
||||
|
||||
// Reset Account if caServer changed, thus registration URI can be updated
|
||||
if p.account != nil && p.account.Registration != nil && !strings.HasPrefix(p.account.Registration.URI, p.CAServer) {
|
||||
p.account = nil
|
||||
}
|
||||
|
||||
p.certificates, err = p.Store.GetCertificates()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get ACME certificates : %v", err)
|
||||
}
|
||||
|
||||
p.watchCertificate()
|
||||
p.watchNewDomains()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) initAccount() (*Account, error) {
|
||||
if p.account == nil || len(p.account.Email) == 0 {
|
||||
var err error
|
||||
p.account, err = NewAccount(p.Email, p.KeyType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return p.account, nil
|
||||
// SetCertificateStore allow to initialize certificate store
|
||||
func (p *Provider) SetCertificateStore(certificateStore *traefiktls.CertificateStore) {
|
||||
p.certificateStore = certificateStore
|
||||
}
|
||||
|
||||
// ListenConfiguration sets a new Configuration into the configFromListenerChan
|
||||
@ -150,94 +110,78 @@ func (p *Provider) ListenRequest(domain string) (*tls.Certificate, error) {
|
||||
return &certificate, err
|
||||
}
|
||||
|
||||
func (p *Provider) watchNewDomains() {
|
||||
p.pool.Go(func(stop chan bool) {
|
||||
for {
|
||||
select {
|
||||
case config := <-p.configFromListenerChan:
|
||||
for _, frontend := range config.Frontends {
|
||||
for _, route := range frontend.Routes {
|
||||
domainRules := rules.Rules{}
|
||||
domains, err := domainRules.ParseDomains(route.Rule)
|
||||
// Provide allows the file provider to provide configurations to traefik
|
||||
// using the given Configuration channel.
|
||||
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
|
||||
p.pool = pool
|
||||
err := p.init()
|
||||
if err != nil {
|
||||
log.Errorf("Error parsing domains in provider ACME: %v", err)
|
||||
continue
|
||||
return err
|
||||
}
|
||||
|
||||
if len(domains) == 0 {
|
||||
log.Debugf("No domain parsed in rule %q", route.Rule)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debugf("Try to challenge certificate for domain %v founded in Host rule", domains)
|
||||
|
||||
var domain types.Domain
|
||||
if len(domains) > 0 {
|
||||
domain = types.Domain{Main: domains[0]}
|
||||
if len(domains) > 1 {
|
||||
domain.SANs = domains[1:]
|
||||
}
|
||||
p.configurationChan = configurationChan
|
||||
p.refreshCertificates()
|
||||
|
||||
p.deleteUnnecessaryDomains()
|
||||
for i := 0; i < len(p.Domains); i++ {
|
||||
domain := p.Domains[i]
|
||||
safe.Go(func() {
|
||||
if _, err := p.resolveCertificate(domain, false); err != nil {
|
||||
log.Errorf("Unable to obtain ACME certificate for domains %q detected thanks to rule %q : %v", strings.Join(domains, ","), route.Rule, err)
|
||||
if _, err := p.resolveCertificate(domain, true); err != nil {
|
||||
log.Errorf("Unable to obtain ACME certificate for domains %q : %v", strings.Join(domain.ToStrArray(), ","), err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.renewCertificates()
|
||||
|
||||
ticker := time.NewTicker(24 * time.Hour)
|
||||
pool.Go(func(stop chan bool) {
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
p.renewCertificates()
|
||||
case <-stop:
|
||||
ticker.Stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetCertificateStore allow to initialize certificate store
|
||||
func (p *Provider) SetCertificateStore(certificateStore *traefiktls.CertificateStore) {
|
||||
p.certificateStore = certificateStore
|
||||
}
|
||||
|
||||
func (p *Provider) resolveCertificate(domain types.Domain, domainFromConfigurationFile bool) (*acme.CertificateResource, error) {
|
||||
domains, err := p.getValidDomains(domain, domainFromConfigurationFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check provided certificates
|
||||
uncheckedDomains := p.getUncheckedDomains(domains, !domainFromConfigurationFile)
|
||||
if len(uncheckedDomains) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
log.Debugf("Loading ACME certificates %+v...", uncheckedDomains)
|
||||
|
||||
client, err := p.getClient()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get ACME client %v", err)
|
||||
}
|
||||
|
||||
bundle := true
|
||||
|
||||
certificate, err := client.ObtainCertificate(uncheckedDomains, bundle, nil, OSCPMustStaple)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot obtain certificates: %+v", err)
|
||||
}
|
||||
|
||||
if len(certificate.Certificate) == 0 || len(certificate.PrivateKey) == 0 {
|
||||
return nil, fmt.Errorf("domains %v generate certificate with no value: %v", uncheckedDomains, certificate)
|
||||
}
|
||||
|
||||
log.Debugf("Certificates obtained for domains %+v", uncheckedDomains)
|
||||
|
||||
if len(uncheckedDomains) > 1 {
|
||||
domain = types.Domain{Main: uncheckedDomains[0], SANs: uncheckedDomains[1:]}
|
||||
func (p *Provider) init() error {
|
||||
acme.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
|
||||
if p.ACMELogging {
|
||||
legolog.Logger = fmtlog.New(log.WriterLevel(logrus.InfoLevel), "legolog: ", 0)
|
||||
} else {
|
||||
domain = types.Domain{Main: uncheckedDomains[0]}
|
||||
legolog.Logger = fmtlog.New(ioutil.Discard, "", 0)
|
||||
}
|
||||
p.addCertificateForDomain(domain, certificate.Certificate, certificate.PrivateKey)
|
||||
|
||||
return certificate, nil
|
||||
if p.Store == nil {
|
||||
return errors.New("no store found for the ACME provider")
|
||||
}
|
||||
|
||||
var err error
|
||||
p.account, err = p.Store.GetAccount()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get ACME account : %v", err)
|
||||
}
|
||||
|
||||
// Reset Account if caServer changed, thus registration URI can be updated
|
||||
if p.account != nil && p.account.Registration != nil && !strings.HasPrefix(p.account.Registration.URI, p.CAServer) {
|
||||
p.account = nil
|
||||
}
|
||||
|
||||
p.certificates, err = p.Store.GetCertificates()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get ACME certificates : %v", err)
|
||||
}
|
||||
|
||||
p.watchCertificate()
|
||||
p.watchNewDomains()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) getClient() (*acme.Client, error) {
|
||||
@ -299,7 +243,7 @@ func (p *Provider) getClient() (*acme.Client, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01})
|
||||
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.TLSALPN01})
|
||||
|
||||
err = client.SetChallengeProvider(acme.DNS01, provider)
|
||||
if err != nil {
|
||||
@ -308,67 +252,140 @@ func (p *Provider) getClient() (*acme.Client, error) {
|
||||
} else if p.HTTPChallenge != nil && len(p.HTTPChallenge.EntryPoint) > 0 {
|
||||
log.Debug("Using HTTP Challenge provider.")
|
||||
|
||||
client.ExcludeChallenges([]acme.Challenge{acme.DNS01})
|
||||
client.ExcludeChallenges([]acme.Challenge{acme.DNS01, acme.TLSALPN01})
|
||||
|
||||
err = client.SetChallengeProvider(acme.HTTP01, p)
|
||||
err = client.SetChallengeProvider(acme.HTTP01, &challengeHTTP{Store: p.Store})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if p.TLSChallenge != nil {
|
||||
log.Debug("Using TLS Challenge provider.")
|
||||
|
||||
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.DNS01})
|
||||
|
||||
err = client.SetChallengeProvider(acme.TLSALPN01, &challengeTLSALPN{Store: p.Store})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, errors.New("ACME challenge not specified, please select HTTP or DNS Challenge")
|
||||
return nil, errors.New("ACME challenge not specified, please select TLS or HTTP or DNS Challenge")
|
||||
}
|
||||
|
||||
p.client = client
|
||||
return p.client, nil
|
||||
}
|
||||
|
||||
// Present presents a challenge to obtain new ACME certificate
|
||||
func (p *Provider) Present(domain, token, keyAuth string) error {
|
||||
return presentHTTPChallenge(domain, token, keyAuth, p.Store)
|
||||
}
|
||||
|
||||
// CleanUp cleans the challenges when certificate is obtained
|
||||
func (p *Provider) CleanUp(domain, token, keyAuth string) error {
|
||||
return cleanUpHTTPChallenge(domain, token, p.Store)
|
||||
}
|
||||
|
||||
// Provide allows the file provider to provide configurations to traefik
|
||||
// using the given Configuration channel.
|
||||
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
|
||||
p.pool = pool
|
||||
err := p.init()
|
||||
func (p *Provider) initAccount() (*Account, error) {
|
||||
if p.account == nil || len(p.account.Email) == 0 {
|
||||
var err error
|
||||
p.account, err = NewAccount(p.Email, p.KeyType)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return p.account, nil
|
||||
}
|
||||
|
||||
func (p *Provider) watchNewDomains() {
|
||||
p.pool.Go(func(stop chan bool) {
|
||||
for {
|
||||
select {
|
||||
case config := <-p.configFromListenerChan:
|
||||
for _, frontend := range config.Frontends {
|
||||
for _, route := range frontend.Routes {
|
||||
domainRules := rules.Rules{}
|
||||
domains, err := domainRules.ParseDomains(route.Rule)
|
||||
if err != nil {
|
||||
log.Errorf("Error parsing domains in provider ACME: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
p.configurationChan = configurationChan
|
||||
p.refreshCertificates()
|
||||
if len(domains) == 0 {
|
||||
log.Debugf("No domain parsed in rule %q", route.Rule)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debugf("Try to challenge certificate for domain %v founded in Host rule", domains)
|
||||
|
||||
var domain types.Domain
|
||||
if len(domains) > 0 {
|
||||
domain = types.Domain{Main: domains[0]}
|
||||
if len(domains) > 1 {
|
||||
domain.SANs = domains[1:]
|
||||
}
|
||||
|
||||
p.deleteUnnecessaryDomains()
|
||||
for i := 0; i < len(p.Domains); i++ {
|
||||
domain := p.Domains[i]
|
||||
safe.Go(func() {
|
||||
if _, err := p.resolveCertificate(domain, true); err != nil {
|
||||
log.Errorf("Unable to obtain ACME certificate for domains %q : %v", strings.Join(domain.ToStrArray(), ","), err)
|
||||
if _, err := p.resolveCertificate(domain, false); err != nil {
|
||||
log.Errorf("Unable to obtain ACME certificate for domains %q detected thanks to rule %q : %v", strings.Join(domains, ","), route.Rule, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
p.renewCertificates()
|
||||
|
||||
ticker := time.NewTicker(24 * time.Hour)
|
||||
pool.Go(func(stop chan bool) {
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
p.renewCertificates()
|
||||
}
|
||||
}
|
||||
case <-stop:
|
||||
ticker.Stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Provider) resolveCertificate(domain types.Domain, domainFromConfigurationFile bool) (*acme.CertificateResource, error) {
|
||||
domains, err := p.getValidDomains(domain, domainFromConfigurationFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check provided certificates
|
||||
uncheckedDomains := p.getUncheckedDomains(domains, !domainFromConfigurationFile)
|
||||
if len(uncheckedDomains) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
log.Debugf("Loading ACME certificates %+v...", uncheckedDomains)
|
||||
|
||||
client, err := p.getClient()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get ACME client %v", err)
|
||||
}
|
||||
|
||||
bundle := true
|
||||
|
||||
certificate, err := client.ObtainCertificate(uncheckedDomains, bundle, nil, OSCPMustStaple)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot obtain certificates: %+v", err)
|
||||
}
|
||||
|
||||
if len(certificate.Certificate) == 0 || len(certificate.PrivateKey) == 0 {
|
||||
return nil, fmt.Errorf("domains %v generate certificate with no value: %v", uncheckedDomains, certificate)
|
||||
}
|
||||
|
||||
log.Debugf("Certificates obtained for domains %+v", uncheckedDomains)
|
||||
|
||||
if len(uncheckedDomains) > 1 {
|
||||
domain = types.Domain{Main: uncheckedDomains[0], SANs: uncheckedDomains[1:]}
|
||||
} else {
|
||||
domain = types.Domain{Main: uncheckedDomains[0]}
|
||||
}
|
||||
p.addCertificateForDomain(domain, certificate.Certificate, certificate.PrivateKey)
|
||||
|
||||
return certificate, nil
|
||||
}
|
||||
|
||||
func dnsOverrideDelay(delay flaeg.Duration) error {
|
||||
if delay == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if delay > 0 {
|
||||
log.Debugf("Delaying %d rather than validating DNS propagation now.", delay)
|
||||
|
||||
acme.PreCheckDNS = func(_, _ string) (bool, error) {
|
||||
time.Sleep(time.Duration(delay))
|
||||
return true, nil
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("delayBeforeCheck: %d cannot be less than 0", delay)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -376,219 +393,6 @@ func (p *Provider) addCertificateForDomain(domain types.Domain, certificate []by
|
||||
p.certsChan <- &Certificate{Certificate: certificate, Key: key, Domain: domain}
|
||||
}
|
||||
|
||||
func (p *Provider) watchCertificate() {
|
||||
p.certsChan = make(chan *Certificate)
|
||||
p.pool.Go(func(stop chan bool) {
|
||||
for {
|
||||
select {
|
||||
case cert := <-p.certsChan:
|
||||
certUpdated := false
|
||||
for _, domainsCertificate := range p.certificates {
|
||||
if reflect.DeepEqual(cert.Domain, domainsCertificate.Domain) {
|
||||
domainsCertificate.Certificate = cert.Certificate
|
||||
domainsCertificate.Key = cert.Key
|
||||
certUpdated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !certUpdated {
|
||||
p.certificates = append(p.certificates, cert)
|
||||
}
|
||||
p.saveCertificates()
|
||||
|
||||
case <-stop:
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Provider) saveCertificates() {
|
||||
err := p.Store.SaveCertificates(p.certificates)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
p.refreshCertificates()
|
||||
}
|
||||
|
||||
func (p *Provider) refreshCertificates() {
|
||||
config := types.ConfigMessage{
|
||||
ProviderName: "ACME",
|
||||
Configuration: &types.Configuration{
|
||||
Backends: map[string]*types.Backend{},
|
||||
Frontends: map[string]*types.Frontend{},
|
||||
TLS: []*traefiktls.Configuration{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, cert := range p.certificates {
|
||||
certificate := &traefiktls.Certificate{CertFile: traefiktls.FileOrContent(cert.Certificate), KeyFile: traefiktls.FileOrContent(cert.Key)}
|
||||
config.Configuration.TLS = append(config.Configuration.TLS, &traefiktls.Configuration{Certificate: certificate, EntryPoints: []string{p.EntryPoint}})
|
||||
}
|
||||
p.configurationChan <- config
|
||||
}
|
||||
|
||||
// Timeout calculates the maximum of time allowed to resolved an ACME challenge
|
||||
func (p *Provider) Timeout() (timeout, interval time.Duration) {
|
||||
return 60 * time.Second, 5 * time.Second
|
||||
}
|
||||
|
||||
func (p *Provider) renewCertificates() {
|
||||
log.Info("Testing certificate renew...")
|
||||
for _, certificate := range p.certificates {
|
||||
crt, err := getX509Certificate(certificate)
|
||||
// If there's an error, we assume the cert is broken, and needs update
|
||||
// <= 30 days left, renew certificate
|
||||
if err != nil || crt == nil || crt.NotAfter.Before(time.Now().Add(24*30*time.Hour)) {
|
||||
client, err := p.getClient()
|
||||
if err != nil {
|
||||
log.Infof("Error renewing certificate from LE : %+v, %v", certificate.Domain, err)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Infof("Renewing certificate from LE : %+v", certificate.Domain)
|
||||
|
||||
renewedCert, err := client.RenewCertificate(acme.CertificateResource{
|
||||
Domain: certificate.Domain.Main,
|
||||
PrivateKey: certificate.Key,
|
||||
Certificate: certificate.Certificate,
|
||||
}, true, OSCPMustStaple)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("Error renewing certificate from LE: %v, %v", certificate.Domain, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(renewedCert.Certificate) == 0 || len(renewedCert.PrivateKey) == 0 {
|
||||
log.Errorf("domains %v renew certificate with no value: %v", certificate.Domain.ToStrArray(), certificate)
|
||||
continue
|
||||
}
|
||||
|
||||
p.addCertificateForDomain(certificate.Domain, renewedCert.Certificate, renewedCert.PrivateKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddRoutes add routes on internal router
|
||||
func (p *Provider) AddRoutes(router *mux.Router) {
|
||||
router.Methods(http.MethodGet).
|
||||
Path(acme.HTTP01ChallengePath("{token}")).
|
||||
Handler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
vars := mux.Vars(req)
|
||||
if token, ok := vars["token"]; ok {
|
||||
domain, _, err := net.SplitHostPort(req.Host)
|
||||
if err != nil {
|
||||
log.Debugf("Unable to split host and port: %v. Fallback to request host.", err)
|
||||
domain = req.Host
|
||||
}
|
||||
|
||||
tokenValue := getTokenValue(token, domain, p.Store)
|
||||
if len(tokenValue) > 0 {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
_, err = rw.Write(tokenValue)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to write token : %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
rw.WriteHeader(http.StatusNotFound)
|
||||
}))
|
||||
}
|
||||
|
||||
// Get provided certificate which check a domains list (Main and SANs)
|
||||
// from static and dynamic provided certificates
|
||||
func (p *Provider) getUncheckedDomains(domainsToCheck []string, checkConfigurationDomains bool) []string {
|
||||
log.Debugf("Looking for provided certificate(s) to validate %q...", domainsToCheck)
|
||||
var allDomains []string
|
||||
|
||||
allDomains = p.certificateStore.GetAllDomains()
|
||||
|
||||
// Get ACME certificates
|
||||
for _, certificate := range p.certificates {
|
||||
allDomains = append(allDomains, strings.Join(certificate.Domain.ToStrArray(), ","))
|
||||
}
|
||||
|
||||
// Get Configuration Domains
|
||||
if checkConfigurationDomains {
|
||||
for i := 0; i < len(p.Domains); i++ {
|
||||
allDomains = append(allDomains, strings.Join(p.Domains[i].ToStrArray(), ","))
|
||||
}
|
||||
}
|
||||
|
||||
return searchUncheckedDomains(domainsToCheck, allDomains)
|
||||
}
|
||||
|
||||
func searchUncheckedDomains(domainsToCheck []string, existentDomains []string) []string {
|
||||
var uncheckedDomains []string
|
||||
for _, domainToCheck := range domainsToCheck {
|
||||
if !isDomainAlreadyChecked(domainToCheck, existentDomains) {
|
||||
uncheckedDomains = append(uncheckedDomains, domainToCheck)
|
||||
}
|
||||
}
|
||||
if len(uncheckedDomains) == 0 {
|
||||
log.Debugf("No ACME certificate to generate for domains %q.", domainsToCheck)
|
||||
} else {
|
||||
log.Debugf("Domains %q need ACME certificates generation for domains %q.", domainsToCheck, strings.Join(uncheckedDomains, ","))
|
||||
}
|
||||
return uncheckedDomains
|
||||
}
|
||||
|
||||
func getX509Certificate(certificate *Certificate) (*x509.Certificate, error) {
|
||||
var crt *x509.Certificate
|
||||
tlsCert, err := tls.X509KeyPair(certificate.Certificate, certificate.Key)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to load TLS keypair from ACME certificate for domain %q (SAN : %q), certificate will be renewed : %v", certificate.Domain.Main, strings.Join(certificate.Domain.SANs, ","), err)
|
||||
return nil, err
|
||||
}
|
||||
crt = tlsCert.Leaf
|
||||
if crt == nil {
|
||||
crt, err = x509.ParseCertificate(tlsCert.Certificate[0])
|
||||
if err != nil {
|
||||
log.Errorf("Failed to parse TLS keypair from ACME certificate for domain %q (SAN : %q), certificate will be renewed : %v", certificate.Domain.Main, strings.Join(certificate.Domain.SANs, ","), err)
|
||||
}
|
||||
}
|
||||
return crt, err
|
||||
}
|
||||
|
||||
// getValidDomains checks if given domain is allowed to generate a ACME certificate and return it
|
||||
func (p *Provider) getValidDomains(domain types.Domain, wildcardAllowed bool) ([]string, error) {
|
||||
domains := domain.ToStrArray()
|
||||
if len(domains) == 0 {
|
||||
return nil, errors.New("unable to generate a certificate in ACME provider when no domain is given")
|
||||
}
|
||||
if strings.HasPrefix(domain.Main, "*") {
|
||||
if !wildcardAllowed {
|
||||
return nil, fmt.Errorf("unable to generate a wildcard certificate in ACME provider for domain %q from a 'Host' rule", strings.Join(domains, ","))
|
||||
}
|
||||
if p.DNSChallenge == nil {
|
||||
return nil, fmt.Errorf("unable to generate a wildcard certificate in ACME provider for domain %q : ACME needs a DNSChallenge", strings.Join(domains, ","))
|
||||
}
|
||||
if strings.HasPrefix(domain.Main, "*.*") {
|
||||
return nil, fmt.Errorf("unable to generate a wildcard certificate in ACME provider for domain %q : ACME does not allow '*.*' wildcard domain", strings.Join(domains, ","))
|
||||
}
|
||||
}
|
||||
for _, san := range domain.SANs {
|
||||
if strings.HasPrefix(san, "*") {
|
||||
return nil, fmt.Errorf("unable to generate a certificate in ACME provider for domains %q: SAN %q can not be a wildcard domain", strings.Join(domains, ","), san)
|
||||
}
|
||||
}
|
||||
|
||||
domains = fun.Map(types.CanonicalDomain, domains).([]string)
|
||||
return domains, nil
|
||||
}
|
||||
|
||||
func isDomainAlreadyChecked(domainToCheck string, existentDomains []string) bool {
|
||||
for _, certDomains := range existentDomains {
|
||||
for _, certDomain := range strings.Split(certDomains, ",") {
|
||||
if types.MatchDomain(domainToCheck, certDomain) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// deleteUnnecessaryDomains deletes from the configuration :
|
||||
// - Duplicated domains
|
||||
// - Domains which are checked by wildcard domain
|
||||
@ -643,3 +447,193 @@ func (p *Provider) deleteUnnecessaryDomains() {
|
||||
|
||||
p.Domains = newDomains
|
||||
}
|
||||
|
||||
func (p *Provider) watchCertificate() {
|
||||
p.certsChan = make(chan *Certificate)
|
||||
p.pool.Go(func(stop chan bool) {
|
||||
for {
|
||||
select {
|
||||
case cert := <-p.certsChan:
|
||||
certUpdated := false
|
||||
for _, domainsCertificate := range p.certificates {
|
||||
if reflect.DeepEqual(cert.Domain, domainsCertificate.Domain) {
|
||||
domainsCertificate.Certificate = cert.Certificate
|
||||
domainsCertificate.Key = cert.Key
|
||||
certUpdated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !certUpdated {
|
||||
p.certificates = append(p.certificates, cert)
|
||||
}
|
||||
|
||||
err := p.saveCertificates()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
case <-stop:
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Provider) saveCertificates() error {
|
||||
err := p.Store.SaveCertificates(p.certificates)
|
||||
|
||||
p.refreshCertificates()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Provider) refreshCertificates() {
|
||||
config := types.ConfigMessage{
|
||||
ProviderName: "ACME",
|
||||
Configuration: &types.Configuration{
|
||||
Backends: map[string]*types.Backend{},
|
||||
Frontends: map[string]*types.Frontend{},
|
||||
TLS: []*traefiktls.Configuration{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, cert := range p.certificates {
|
||||
certificate := &traefiktls.Certificate{CertFile: traefiktls.FileOrContent(cert.Certificate), KeyFile: traefiktls.FileOrContent(cert.Key)}
|
||||
config.Configuration.TLS = append(config.Configuration.TLS, &traefiktls.Configuration{Certificate: certificate, EntryPoints: []string{p.EntryPoint}})
|
||||
}
|
||||
p.configurationChan <- config
|
||||
}
|
||||
|
||||
func (p *Provider) renewCertificates() {
|
||||
log.Info("Testing certificate renew...")
|
||||
for _, certificate := range p.certificates {
|
||||
crt, err := getX509Certificate(certificate)
|
||||
// If there's an error, we assume the cert is broken, and needs update
|
||||
// <= 30 days left, renew certificate
|
||||
if err != nil || crt == nil || crt.NotAfter.Before(time.Now().Add(24*30*time.Hour)) {
|
||||
client, err := p.getClient()
|
||||
if err != nil {
|
||||
log.Infof("Error renewing certificate from LE : %+v, %v", certificate.Domain, err)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Infof("Renewing certificate from LE : %+v", certificate.Domain)
|
||||
|
||||
renewedCert, err := client.RenewCertificate(acme.CertificateResource{
|
||||
Domain: certificate.Domain.Main,
|
||||
PrivateKey: certificate.Key,
|
||||
Certificate: certificate.Certificate,
|
||||
}, true, OSCPMustStaple)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("Error renewing certificate from LE: %v, %v", certificate.Domain, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(renewedCert.Certificate) == 0 || len(renewedCert.PrivateKey) == 0 {
|
||||
log.Errorf("domains %v renew certificate with no value: %v", certificate.Domain.ToStrArray(), certificate)
|
||||
continue
|
||||
}
|
||||
|
||||
p.addCertificateForDomain(certificate.Domain, renewedCert.Certificate, renewedCert.PrivateKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get provided certificate which check a domains list (Main and SANs)
|
||||
// from static and dynamic provided certificates
|
||||
func (p *Provider) getUncheckedDomains(domainsToCheck []string, checkConfigurationDomains bool) []string {
|
||||
log.Debugf("Looking for provided certificate(s) to validate %q...", domainsToCheck)
|
||||
|
||||
allDomains := p.certificateStore.GetAllDomains()
|
||||
|
||||
// Get ACME certificates
|
||||
for _, certificate := range p.certificates {
|
||||
allDomains = append(allDomains, strings.Join(certificate.Domain.ToStrArray(), ","))
|
||||
}
|
||||
|
||||
// Get Configuration Domains
|
||||
if checkConfigurationDomains {
|
||||
for i := 0; i < len(p.Domains); i++ {
|
||||
allDomains = append(allDomains, strings.Join(p.Domains[i].ToStrArray(), ","))
|
||||
}
|
||||
}
|
||||
|
||||
return searchUncheckedDomains(domainsToCheck, allDomains)
|
||||
}
|
||||
|
||||
func searchUncheckedDomains(domainsToCheck []string, existentDomains []string) []string {
|
||||
var uncheckedDomains []string
|
||||
for _, domainToCheck := range domainsToCheck {
|
||||
if !isDomainAlreadyChecked(domainToCheck, existentDomains) {
|
||||
uncheckedDomains = append(uncheckedDomains, domainToCheck)
|
||||
}
|
||||
}
|
||||
|
||||
if len(uncheckedDomains) == 0 {
|
||||
log.Debugf("No ACME certificate to generate for domains %q.", domainsToCheck)
|
||||
} else {
|
||||
log.Debugf("Domains %q need ACME certificates generation for domains %q.", domainsToCheck, strings.Join(uncheckedDomains, ","))
|
||||
}
|
||||
return uncheckedDomains
|
||||
}
|
||||
|
||||
func getX509Certificate(certificate *Certificate) (*x509.Certificate, error) {
|
||||
tlsCert, err := tls.X509KeyPair(certificate.Certificate, certificate.Key)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to load TLS keypair from ACME certificate for domain %q (SAN : %q), certificate will be renewed : %v", certificate.Domain.Main, strings.Join(certificate.Domain.SANs, ","), err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
crt := tlsCert.Leaf
|
||||
if crt == nil {
|
||||
crt, err = x509.ParseCertificate(tlsCert.Certificate[0])
|
||||
if err != nil {
|
||||
log.Errorf("Failed to parse TLS keypair from ACME certificate for domain %q (SAN : %q), certificate will be renewed : %v", certificate.Domain.Main, strings.Join(certificate.Domain.SANs, ","), err)
|
||||
}
|
||||
}
|
||||
|
||||
return crt, err
|
||||
}
|
||||
|
||||
// getValidDomains checks if given domain is allowed to generate a ACME certificate and return it
|
||||
func (p *Provider) getValidDomains(domain types.Domain, wildcardAllowed bool) ([]string, error) {
|
||||
domains := domain.ToStrArray()
|
||||
if len(domains) == 0 {
|
||||
return nil, errors.New("unable to generate a certificate in ACME provider when no domain is given")
|
||||
}
|
||||
|
||||
if strings.HasPrefix(domain.Main, "*") {
|
||||
if !wildcardAllowed {
|
||||
return nil, fmt.Errorf("unable to generate a wildcard certificate in ACME provider for domain %q from a 'Host' rule", strings.Join(domains, ","))
|
||||
}
|
||||
|
||||
if p.DNSChallenge == nil {
|
||||
return nil, fmt.Errorf("unable to generate a wildcard certificate in ACME provider for domain %q : ACME needs a DNSChallenge", strings.Join(domains, ","))
|
||||
}
|
||||
|
||||
if strings.HasPrefix(domain.Main, "*.*") {
|
||||
return nil, fmt.Errorf("unable to generate a wildcard certificate in ACME provider for domain %q : ACME does not allow '*.*' wildcard domain", strings.Join(domains, ","))
|
||||
}
|
||||
}
|
||||
|
||||
for _, san := range domain.SANs {
|
||||
if strings.HasPrefix(san, "*") {
|
||||
return nil, fmt.Errorf("unable to generate a certificate in ACME provider for domains %q: SAN %q can not be a wildcard domain", strings.Join(domains, ","), san)
|
||||
}
|
||||
}
|
||||
|
||||
domains = fun.Map(types.CanonicalDomain, domains).([]string)
|
||||
return domains, nil
|
||||
}
|
||||
|
||||
func isDomainAlreadyChecked(domainToCheck string, existentDomains []string) bool {
|
||||
for _, certDomains := range existentDomains {
|
||||
for _, certDomain := range strings.Split(certDomains, ",") {
|
||||
if types.MatchDomain(domainToCheck, certDomain) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ type StoredData struct {
|
||||
Account *Account
|
||||
Certificates []*Certificate
|
||||
HTTPChallenges map[string]map[string][]byte
|
||||
TLSChallenges map[string]*Certificate
|
||||
}
|
||||
|
||||
// Store is a generic interface to represents a storage
|
||||
@ -13,6 +14,11 @@ type Store interface {
|
||||
SaveAccount(*Account) error
|
||||
GetCertificates() ([]*Certificate, error)
|
||||
SaveCertificates([]*Certificate) error
|
||||
|
||||
GetHTTPChallenges() (map[string]map[string][]byte, error)
|
||||
SaveHTTPChallenges(map[string]map[string][]byte) error
|
||||
|
||||
AddTLSChallenge(domain string, cert *Certificate) error
|
||||
GetTLSChallenge(domain string) (*Certificate, error)
|
||||
RemoveTLSChallenge(domain string) error
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import (
|
||||
"github.com/containous/traefik/whitelist"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/negroni"
|
||||
"github.com/xenolf/lego/acme"
|
||||
)
|
||||
|
||||
var httpServerLogger = stdlog.New(log.WriterLevel(logrus.DebugLevel), "", 0)
|
||||
@ -68,6 +69,7 @@ type EntryPoint struct {
|
||||
InternalRouter types.InternalRouter
|
||||
Configuration *configuration.EntryPoint
|
||||
OnDemandListener func(string) (*tls.Certificate, error)
|
||||
TLSALPNGetter func(string) (*tls.Certificate, error)
|
||||
CertificateStore *traefiktls.CertificateStore
|
||||
}
|
||||
|
||||
@ -79,6 +81,7 @@ type serverEntryPoint struct {
|
||||
httpRouter *middlewares.HandlerSwitcher
|
||||
certs *safe.Safe
|
||||
onDemandListener func(string) (*tls.Certificate, error)
|
||||
tlsALPNGetter func(string) (*tls.Certificate, error)
|
||||
}
|
||||
|
||||
// NewServer returns an initialized Server.
|
||||
@ -274,6 +277,7 @@ func (s *Server) AddListener(listener func(types.Configuration)) {
|
||||
// getCertificate allows to customize tlsConfig.GetCertificate behaviour to get the certificates inserted dynamically
|
||||
func (s *serverEntryPoint) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
domainToCheck := types.CanonicalDomain(clientHello.ServerName)
|
||||
|
||||
if s.certs.Get() != nil {
|
||||
for domains, cert := range s.certs.Get().(map[string]*tls.Certificate) {
|
||||
for _, certDomain := range strings.Split(domains, ",") {
|
||||
@ -284,9 +288,22 @@ func (s *serverEntryPoint) getCertificate(clientHello *tls.ClientHelloInfo) (*tl
|
||||
}
|
||||
log.Debugf("No certificate provided dynamically can check the domain %q, a per default certificate will be used.", domainToCheck)
|
||||
}
|
||||
|
||||
if s.tlsALPNGetter != nil {
|
||||
cert, err := s.tlsALPNGetter(domainToCheck)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cert != nil {
|
||||
return cert, nil
|
||||
}
|
||||
}
|
||||
|
||||
if s.onDemandListener != nil {
|
||||
return s.onDemandListener(domainToCheck)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -319,8 +336,9 @@ func (s *Server) createTLSConfig(entryPointName string, tlsOption *traefiktls.TL
|
||||
}
|
||||
|
||||
s.serverEntryPoints[entryPointName].certs.Set(make(map[string]*tls.Certificate))
|
||||
|
||||
// ensure http2 enabled
|
||||
config.NextProtos = []string{"h2", "http/1.1"}
|
||||
config.NextProtos = []string{"h2", "http/1.1", acme.ACMETLS1Protocol}
|
||||
|
||||
if len(tlsOption.ClientCAFiles) > 0 {
|
||||
log.Warnf("Deprecated configuration found during TLS configuration creation: %s. Please use %s (which allows to make the CA Files optional).", "tls.ClientCAFiles", "tls.ClientCA.files")
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
traefiktls "github.com/containous/traefik/tls"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/eapache/channels"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/negroni"
|
||||
"github.com/vulcand/oxy/forward"
|
||||
)
|
||||
@ -291,9 +292,10 @@ func (s *Server) preLoadConfiguration(configMsg types.ConfigMessage) {
|
||||
s.defaultConfigurationValues(configMsg.Configuration)
|
||||
currentConfigurations := s.currentConfigurations.Get().(types.Configurations)
|
||||
|
||||
if log.GetLevel() == logrus.DebugLevel {
|
||||
jsonConf, _ := json.Marshal(configMsg.Configuration)
|
||||
|
||||
log.Debugf("Configuration received from provider %s: %s", configMsg.ProviderName, string(jsonConf))
|
||||
}
|
||||
|
||||
if configMsg.Configuration == nil || configMsg.Configuration.Backends == nil && configMsg.Configuration.Frontends == nil && configMsg.Configuration.TLS == nil {
|
||||
log.Infof("Skipping empty Configuration for provider %s", configMsg.ProviderName)
|
||||
@ -553,6 +555,7 @@ func (s *Server) buildServerEntryPoints() map[string]*serverEntryPoint {
|
||||
serverEntryPoints[entryPointName] = &serverEntryPoint{
|
||||
httpRouter: middlewares.NewHandlerSwitcher(s.buildDefaultHTTPRouter()),
|
||||
onDemandListener: entryPoint.OnDemandListener,
|
||||
tlsALPNGetter: entryPoint.TLSALPNGetter,
|
||||
}
|
||||
if entryPoint.CertificateStore != nil {
|
||||
serverEntryPoints[entryPointName].certs = entryPoint.CertificateStore.DynamicCerts
|
||||
|
@ -1,7 +1,6 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
@ -15,6 +14,9 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// DefaultDomain Traefik domain for the default certificate
|
||||
const DefaultDomain = "TRAEFIK DEFAULT CERT"
|
||||
|
||||
// DefaultCertificate generates random TLS certificates
|
||||
func DefaultCertificate() (*tls.Certificate, error) {
|
||||
randomBytes := make([]byte, 100)
|
||||
@ -78,7 +80,7 @@ func derCert(privKey *rsa.PrivateKey, expiration time.Time, domain string) ([]by
|
||||
template := x509.Certificate{
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
CommonName: "TRAEFIK DEFAULT CERT",
|
||||
CommonName: DefaultDomain,
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: expiration,
|
||||
@ -90,21 +92,3 @@ func derCert(privKey *rsa.PrivateKey, expiration time.Time, domain string) ([]by
|
||||
|
||||
return x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey)
|
||||
}
|
||||
|
||||
// PemEncode encodes date in PEM format
|
||||
func PemEncode(data interface{}) []byte {
|
||||
var pemBlock *pem.Block
|
||||
switch key := data.(type) {
|
||||
case *ecdsa.PrivateKey:
|
||||
keyBytes, _ := x509.MarshalECPrivateKey(key)
|
||||
pemBlock = &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes}
|
||||
case *rsa.PrivateKey:
|
||||
pemBlock = &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)}
|
||||
case *x509.CertificateRequest:
|
||||
pemBlock = &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: key.Raw}
|
||||
case []byte:
|
||||
pemBlock = &pem.Block{Type: "CERTIFICATE", Bytes: data.([]byte)}
|
||||
}
|
||||
|
||||
return pem.EncodeToMemory(pemBlock)
|
||||
}
|
||||
|
13
vendor/github.com/OpenDNS/vegadns2client/LICENSE
generated
vendored
Normal file
13
vendor/github.com/OpenDNS/vegadns2client/LICENSE
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
Copyright 2018, Cisco Systems, Inc.
|
||||
|
||||
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.
|
71
vendor/github.com/OpenDNS/vegadns2client/client.go
generated
vendored
Normal file
71
vendor/github.com/OpenDNS/vegadns2client/client.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
package vegadns2client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// VegaDNSClient - Struct for holding VegaDNSClient specific attributes
|
||||
type VegaDNSClient struct {
|
||||
client http.Client
|
||||
baseurl string
|
||||
version string
|
||||
User string
|
||||
Pass string
|
||||
APIKey string
|
||||
APISecret string
|
||||
token Token
|
||||
}
|
||||
|
||||
// Send - Central place for sending requests
|
||||
// Input: method, endpoint, params
|
||||
// Output: *http.Response
|
||||
func (vega *VegaDNSClient) Send(method string, endpoint string, params map[string]string) (*http.Response, error) {
|
||||
vegaURL := vega.getURL(endpoint)
|
||||
|
||||
p := url.Values{}
|
||||
for k, v := range params {
|
||||
p.Set(k, v)
|
||||
}
|
||||
|
||||
var err error
|
||||
var req *http.Request
|
||||
|
||||
if (method == "GET") || (method == "DELETE") {
|
||||
vegaURL = fmt.Sprintf("%s?%s", vegaURL, p.Encode())
|
||||
req, err = http.NewRequest(method, vegaURL, nil)
|
||||
} else {
|
||||
req, err = http.NewRequest(method, vegaURL, strings.NewReader(p.Encode()))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error preparing request: %s", err)
|
||||
}
|
||||
|
||||
if vega.User != "" && vega.Pass != "" {
|
||||
// Basic Auth
|
||||
req.SetBasicAuth(vega.User, vega.Pass)
|
||||
} else if vega.APIKey != "" && vega.APISecret != "" {
|
||||
// OAuth
|
||||
vega.getAuthToken()
|
||||
err = vega.token.valid()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Authorization", vega.getBearer())
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
return vega.client.Do(req)
|
||||
}
|
||||
|
||||
func (vega *VegaDNSClient) getURL(endpoint string) string {
|
||||
return fmt.Sprintf("%s/%s/%s", vega.baseurl, vega.version, endpoint)
|
||||
}
|
||||
|
||||
func (vega *VegaDNSClient) stillAuthorized() error {
|
||||
return vega.token.valid()
|
||||
}
|
80
vendor/github.com/OpenDNS/vegadns2client/domains.go
generated
vendored
Normal file
80
vendor/github.com/OpenDNS/vegadns2client/domains.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
package vegadns2client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Domain - struct containing a domain object
|
||||
type Domain struct {
|
||||
Status string `json:"status"`
|
||||
Domain string `json:"domain"`
|
||||
DomainID int `json:"domain_id"`
|
||||
OwnerID int `json:"owner_id"`
|
||||
}
|
||||
|
||||
// DomainResponse - api response of a domain list
|
||||
type DomainResponse struct {
|
||||
Status string `json:"status"`
|
||||
Total int `json:"total_domains"`
|
||||
Domains []Domain `json:"domains"`
|
||||
}
|
||||
|
||||
// GetDomainID - returns the id for a domain
|
||||
// Input: domain
|
||||
// Output: int, err
|
||||
func (vega *VegaDNSClient) GetDomainID(domain string) (int, error) {
|
||||
params := make(map[string]string)
|
||||
params["search"] = domain
|
||||
|
||||
resp, err := vega.Send("GET", "domains", params)
|
||||
|
||||
if err != nil {
|
||||
return -1, fmt.Errorf("Error sending GET to GetDomainID: %s", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return -1, fmt.Errorf("Error reading response from GET to GetDomainID: %s", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return -1, fmt.Errorf("Got bad answer from VegaDNS on GetDomainID. Code: %d. Message: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
answer := DomainResponse{}
|
||||
if err := json.Unmarshal(body, &answer); err != nil {
|
||||
return -1, fmt.Errorf("Error unmarshalling body from GetDomainID: %s", err)
|
||||
}
|
||||
log.Println(answer)
|
||||
for _, d := range answer.Domains {
|
||||
if d.Domain == domain {
|
||||
return d.DomainID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return -1, fmt.Errorf("Didnt find domain %s", domain)
|
||||
|
||||
}
|
||||
|
||||
// GetAuthZone retrieves the closest match to a given
|
||||
// domain. Example: Given an argument "a.b.c.d.e", and a VegaDNS
|
||||
// hosted domain of "c.d.e", GetClosestMatchingDomain will return
|
||||
// "c.d.e".
|
||||
func (vega *VegaDNSClient) GetAuthZone(fqdn string) (string, int, error) {
|
||||
fqdn = strings.TrimSuffix(fqdn, ".")
|
||||
numComponents := len(strings.Split(fqdn, "."))
|
||||
for i := 1; i < numComponents; i++ {
|
||||
tmpHostname := strings.SplitN(fqdn, ".", i)[i-1]
|
||||
log.Printf("tmpHostname for i = %d: %s\n", i, tmpHostname)
|
||||
if domainID, err := vega.GetDomainID(tmpHostname); err == nil {
|
||||
log.Printf("Found zone: %s\n\tShortened to %s\n", tmpHostname, strings.TrimSuffix(tmpHostname, "."))
|
||||
return strings.TrimSuffix(tmpHostname, "."), domainID, nil
|
||||
}
|
||||
}
|
||||
log.Println("Unable to find hosted zone in vegadns")
|
||||
return "", -1, fmt.Errorf("Unable to find auth zone for fqdn %s", fqdn)
|
||||
}
|
19
vendor/github.com/OpenDNS/vegadns2client/main.go
generated
vendored
Normal file
19
vendor/github.com/OpenDNS/vegadns2client/main.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
package vegadns2client
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NewVegaDNSClient - helper to instantiate a client
|
||||
// Input: url string
|
||||
// Output: VegaDNSClient
|
||||
func NewVegaDNSClient(url string) VegaDNSClient {
|
||||
httpClient := http.Client{Timeout: 15 * time.Second}
|
||||
return VegaDNSClient{
|
||||
client: httpClient,
|
||||
baseurl: url,
|
||||
version: "1.0",
|
||||
token: Token{},
|
||||
}
|
||||
}
|
113
vendor/github.com/OpenDNS/vegadns2client/records.go
generated
vendored
Normal file
113
vendor/github.com/OpenDNS/vegadns2client/records.go
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
package vegadns2client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Record - struct representing a Record object
|
||||
type Record struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
RecordType string `json:"record_type"`
|
||||
TTL int `json:"ttl"`
|
||||
RecordID int `json:"record_id"`
|
||||
LocationID string `json:"location_id"`
|
||||
DomainID int `json:"domain_id"`
|
||||
}
|
||||
|
||||
// RecordsResponse - api response list of records
|
||||
type RecordsResponse struct {
|
||||
Status string `json:"status"`
|
||||
Total int `json:"total_records"`
|
||||
Domain Domain `json:"domain"`
|
||||
Records []Record `json:"records"`
|
||||
}
|
||||
|
||||
// GetRecordID - helper to get the id of a record
|
||||
// Input: domainID, record, recordType
|
||||
// Output: int
|
||||
func (vega *VegaDNSClient) GetRecordID(domainID int, record string, recordType string) (int, error) {
|
||||
params := make(map[string]string)
|
||||
params["domain_id"] = fmt.Sprintf("%d", domainID)
|
||||
|
||||
resp, err := vega.Send("GET", "records", params)
|
||||
|
||||
if err != nil {
|
||||
return -1, fmt.Errorf("Error sending GET to GetRecordID: %s", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return -1, fmt.Errorf("Error reading response from GetRecordID: %s", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return -1, fmt.Errorf("Got bad answer from VegaDNS on GetRecordID. Code: %d. Message: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
answer := RecordsResponse{}
|
||||
if err := json.Unmarshal(body, &answer); err != nil {
|
||||
return -1, fmt.Errorf("Error unmarshalling body from GetRecordID: %s", err)
|
||||
}
|
||||
|
||||
for _, r := range answer.Records {
|
||||
if r.Name == record && r.RecordType == recordType {
|
||||
return r.RecordID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return -1, errors.New("Couldnt find record")
|
||||
}
|
||||
|
||||
// CreateTXT - Creates a TXT record
|
||||
// Input: domainID, fqdn, value, ttl
|
||||
// Output: nil or error
|
||||
func (vega *VegaDNSClient) CreateTXT(domainID int, fqdn string, value string, ttl int) error {
|
||||
params := make(map[string]string)
|
||||
|
||||
params["record_type"] = "TXT"
|
||||
params["ttl"] = fmt.Sprintf("%d", ttl)
|
||||
params["domain_id"] = fmt.Sprintf("%d", domainID)
|
||||
params["name"] = strings.TrimSuffix(fqdn, ".")
|
||||
params["value"] = value
|
||||
|
||||
resp, err := vega.Send("POST", "records", params)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Send POST error in CreateTXT: %s", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error reading POST response in CreateTXT: %s", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusCreated {
|
||||
return fmt.Errorf("Got bad answer from VegaDNS on CreateTXT. Code: %d. Message: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteRecord - deletes a record by id
|
||||
// Input: recordID
|
||||
// Output: nil or error
|
||||
func (vega *VegaDNSClient) DeleteRecord(recordID int) error {
|
||||
resp, err := vega.Send("DELETE", fmt.Sprintf("records/%d", recordID), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Send DELETE error in DeleteTXT: %s", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error reading DELETE response in DeleteTXT: %s", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("Got bad answer from VegaDNS on DeleteTXT. Code: %d. Message: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
74
vendor/github.com/OpenDNS/vegadns2client/tokens.go
generated
vendored
Normal file
74
vendor/github.com/OpenDNS/vegadns2client/tokens.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
package vegadns2client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Token - struct to hold token information
|
||||
type Token struct {
|
||||
Token string `json:"access_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
ExpiresAt time.Time
|
||||
}
|
||||
|
||||
func (t Token) valid() error {
|
||||
if time.Now().UTC().After(t.ExpiresAt) {
|
||||
return errors.New("Token Expired")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vega *VegaDNSClient) getBearer() string {
|
||||
if vega.token.valid() != nil {
|
||||
vega.getAuthToken()
|
||||
}
|
||||
return vega.token.formatBearer()
|
||||
}
|
||||
|
||||
func (t Token) formatBearer() string {
|
||||
return fmt.Sprintf("Bearer %s", t.Token)
|
||||
}
|
||||
|
||||
func (vega *VegaDNSClient) getAuthToken() {
|
||||
tokenEndpoint := vega.getURL("token")
|
||||
v := url.Values{}
|
||||
v.Set("grant_type", "client_credentials")
|
||||
|
||||
req, err := http.NewRequest("POST", tokenEndpoint, strings.NewReader(v.Encode()))
|
||||
if err != nil {
|
||||
log.Fatalf("Error forming POST to getAuthToken: %s", err)
|
||||
}
|
||||
req.SetBasicAuth(vega.APIKey, vega.APISecret)
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
issueTime := time.Now().UTC()
|
||||
resp, err := vega.client.Do(req)
|
||||
if err != nil {
|
||||
log.Fatalf("Error sending POST to getAuthToken: %s", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading response from POST to getAuthToken: %s", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
log.Fatalf("Got bad answer from VegaDNS on getAuthToken. Code: %d. Message: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
if err := json.Unmarshal(body, &vega.token); err != nil {
|
||||
log.Fatalf("Error unmarshalling body of POST to getAuthToken: %s", err)
|
||||
}
|
||||
|
||||
if vega.token.TokenType != "bearer" {
|
||||
log.Fatal("We don't support anything except bearer tokens")
|
||||
}
|
||||
vega.token.ExpiresAt = issueTime.Add(time.Duration(vega.token.ExpiresIn) * time.Second)
|
||||
}
|
207
vendor/github.com/sacloud/libsacloud/LICENSE.txt
generated
vendored
Normal file
207
vendor/github.com/sacloud/libsacloud/LICENSE.txt
generated
vendored
Normal file
@ -0,0 +1,207 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
================================================================================
|
||||
|
||||
Copyright 2015-2018 Kazumichi Yamamoto.
|
||||
|
344
vendor/github.com/sacloud/libsacloud/api/archive.go
generated
vendored
Normal file
344
vendor/github.com/sacloud/libsacloud/api/archive.go
generated
vendored
Normal file
@ -0,0 +1,344 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"github.com/sacloud/libsacloud/sacloud/ostype"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ArchiveAPI アーカイブAPI
|
||||
type ArchiveAPI struct {
|
||||
*baseAPI
|
||||
findFuncMapPerOSType map[ostype.ArchiveOSTypes]func() (*sacloud.Archive, error)
|
||||
}
|
||||
|
||||
var (
|
||||
archiveLatestStableCentOSTags = []string{"current-stable", "distro-centos"}
|
||||
archiveLatestStableCentOS6Tags = []string{"distro-centos", "distro-ver-6.9"}
|
||||
archiveLatestStableUbuntuTags = []string{"current-stable", "distro-ubuntu"}
|
||||
archiveLatestStableDebianTags = []string{"current-stable", "distro-debian"}
|
||||
archiveLatestStableVyOSTags = []string{"current-stable", "distro-vyos"}
|
||||
archiveLatestStableCoreOSTags = []string{"current-stable", "distro-coreos"}
|
||||
archiveLatestStableRancherOSTags = []string{"current-stable", "distro-rancheros"}
|
||||
archiveLatestStableKusanagiTags = []string{"current-stable", "pkg-kusanagi"}
|
||||
archiveLatestStableSophosUTMTags = []string{"current-stable", "pkg-sophosutm"}
|
||||
archiveLatestStableFreeBSDTags = []string{"current-stable", "distro-freebsd"}
|
||||
archiveLatestStableWindows2012Tags = []string{"os-windows", "distro-ver-2012.2"}
|
||||
archiveLatestStableWindows2012RDSTags = []string{"os-windows", "distro-ver-2012.2", "windows-rds"}
|
||||
archiveLatestStableWindows2012RDSOfficeTags = []string{"os-windows", "distro-ver-2012.2", "windows-rds", "with-office"}
|
||||
archiveLatestStableWindows2016Tags = []string{"os-windows", "distro-ver-2016"}
|
||||
archiveLatestStableWindows2016RDSTags = []string{"os-windows", "distro-ver-2016", "windows-rds"}
|
||||
archiveLatestStableWindows2016RDSOfficeTags = []string{"os-windows", "distro-ver-2016", "windows-rds", "with-office"}
|
||||
archiveLatestStableWindows2016SQLServerWeb = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2016", "edition-web"}
|
||||
archiveLatestStableWindows2016SQLServerStandard = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2016", "edition-standard"}
|
||||
archiveLatestStableWindows2016SQLServerStandardAll = []string{"os-windows", "distro-ver-2016", "windows-sqlserver", "sqlserver-2016", "edition-standard", "windows-rds", "with-office"}
|
||||
)
|
||||
|
||||
// NewArchiveAPI アーカイブAPI作成
|
||||
func NewArchiveAPI(client *Client) *ArchiveAPI {
|
||||
api := &ArchiveAPI{
|
||||
baseAPI: &baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "archive"
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
api.findFuncMapPerOSType = map[ostype.ArchiveOSTypes]func() (*sacloud.Archive, error){
|
||||
ostype.CentOS: api.FindLatestStableCentOS,
|
||||
ostype.CentOS6: api.FindLatestStableCentOS6,
|
||||
ostype.Ubuntu: api.FindLatestStableUbuntu,
|
||||
ostype.Debian: api.FindLatestStableDebian,
|
||||
ostype.VyOS: api.FindLatestStableVyOS,
|
||||
ostype.CoreOS: api.FindLatestStableCoreOS,
|
||||
ostype.RancherOS: api.FindLatestStableRancherOS,
|
||||
ostype.Kusanagi: api.FindLatestStableKusanagi,
|
||||
ostype.SophosUTM: api.FindLatestStableSophosUTM,
|
||||
ostype.FreeBSD: api.FindLatestStableFreeBSD,
|
||||
ostype.Windows2012: api.FindLatestStableWindows2012,
|
||||
ostype.Windows2012RDS: api.FindLatestStableWindows2012RDS,
|
||||
ostype.Windows2012RDSOffice: api.FindLatestStableWindows2012RDSOffice,
|
||||
ostype.Windows2016: api.FindLatestStableWindows2016,
|
||||
ostype.Windows2016RDS: api.FindLatestStableWindows2016RDS,
|
||||
ostype.Windows2016RDSOffice: api.FindLatestStableWindows2016RDSOffice,
|
||||
ostype.Windows2016SQLServerWeb: api.FindLatestStableWindows2016SQLServerWeb,
|
||||
ostype.Windows2016SQLServerStandard: api.FindLatestStableWindows2016SQLServerStandard,
|
||||
ostype.Windows2016SQLServerStandardAll: api.FindLatestStableWindows2016SQLServerStandardAll,
|
||||
}
|
||||
|
||||
return api
|
||||
}
|
||||
|
||||
// OpenFTP FTP接続開始
|
||||
func (api *ArchiveAPI) OpenFTP(id int64) (*sacloud.FTPServer, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/ftp", api.getResourceURL(), id)
|
||||
//body = map[string]bool{"ChangePassword": reset}
|
||||
res = &sacloud.Response{}
|
||||
)
|
||||
|
||||
result, err := api.action(method, uri, nil, res)
|
||||
if !result || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.FTPServer, nil
|
||||
}
|
||||
|
||||
// CloseFTP FTP接続終了
|
||||
func (api *ArchiveAPI) CloseFTP(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/ftp", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
|
||||
}
|
||||
|
||||
// SleepWhileCopying コピー終了まで待機
|
||||
func (api *ArchiveAPI) SleepWhileCopying(id int64, timeout time.Duration) error {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// AsyncSleepWhileCopying コピー終了まで待機(非同期)
|
||||
func (api *ArchiveAPI) AsyncSleepWhileCopying(id int64, timeout time.Duration) (chan (interface{}), chan (interface{}), chan (error)) {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return poll(handler, timeout)
|
||||
}
|
||||
|
||||
// CanEditDisk ディスクの修正が可能か判定
|
||||
func (api *ArchiveAPI) CanEditDisk(id int64) (bool, error) {
|
||||
|
||||
archive, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if archive == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// BundleInfoがあれば編集不可
|
||||
if archive.BundleInfo != nil && archive.BundleInfo.HostClass == bundleInfoWindowsHostClass {
|
||||
// Windows
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// SophosUTMであれば編集不可
|
||||
if archive.HasTag("pkg-sophosutm") || archive.IsSophosUTM() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for _, t := range allowDiskEditTags {
|
||||
if archive.HasTag(t) {
|
||||
// 対応OSインストール済みディスク
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ここまできても判定できないならソースに投げる
|
||||
if archive.SourceDisk != nil && archive.SourceDisk.Availability != "discontinued" {
|
||||
return api.client.Disk.CanEditDisk(archive.SourceDisk.ID)
|
||||
}
|
||||
if archive.SourceArchive != nil && archive.SourceArchive.Availability != "discontinued" {
|
||||
return api.client.Archive.CanEditDisk(archive.SourceArchive.ID)
|
||||
}
|
||||
return false, nil
|
||||
|
||||
}
|
||||
|
||||
// GetPublicArchiveIDFromAncestors 祖先の中からパブリックアーカイブのIDを検索
|
||||
func (api *ArchiveAPI) GetPublicArchiveIDFromAncestors(id int64) (int64, bool) {
|
||||
|
||||
emptyID := int64(0)
|
||||
|
||||
archive, err := api.Read(id)
|
||||
if err != nil {
|
||||
return emptyID, false
|
||||
}
|
||||
|
||||
if archive == nil {
|
||||
return emptyID, false
|
||||
}
|
||||
|
||||
// BundleInfoがあれば編集不可
|
||||
if archive.BundleInfo != nil && archive.BundleInfo.HostClass == bundleInfoWindowsHostClass {
|
||||
// Windows
|
||||
return emptyID, false
|
||||
}
|
||||
|
||||
// SophosUTMであれば編集不可
|
||||
if archive.HasTag("pkg-sophosutm") || archive.IsSophosUTM() {
|
||||
return emptyID, false
|
||||
}
|
||||
|
||||
for _, t := range allowDiskEditTags {
|
||||
if archive.HasTag(t) {
|
||||
// 対応OSインストール済みディスク
|
||||
return archive.ID, true
|
||||
}
|
||||
}
|
||||
|
||||
// ここまできても判定できないならソースに投げる
|
||||
if archive.SourceDisk != nil && archive.SourceDisk.Availability != "discontinued" {
|
||||
return api.client.Disk.GetPublicArchiveIDFromAncestors(archive.SourceDisk.ID)
|
||||
}
|
||||
if archive.SourceArchive != nil && archive.SourceArchive.Availability != "discontinued" {
|
||||
return api.client.Archive.GetPublicArchiveIDFromAncestors(archive.SourceArchive.ID)
|
||||
}
|
||||
return emptyID, false
|
||||
|
||||
}
|
||||
|
||||
// FindLatestStableCentOS 安定版最新のCentOSパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableCentOS() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableCentOSTags)
|
||||
}
|
||||
|
||||
// FindLatestStableCentOS6 安定版最新のCentOS6パブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableCentOS6() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableCentOS6Tags)
|
||||
}
|
||||
|
||||
// FindLatestStableDebian 安定版最新のDebianパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableDebian() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableDebianTags)
|
||||
}
|
||||
|
||||
// FindLatestStableUbuntu 安定版最新のUbuntuパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableUbuntu() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableUbuntuTags)
|
||||
}
|
||||
|
||||
// FindLatestStableVyOS 安定版最新のVyOSパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableVyOS() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableVyOSTags)
|
||||
}
|
||||
|
||||
// FindLatestStableCoreOS 安定版最新のCoreOSパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableCoreOS() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableCoreOSTags)
|
||||
}
|
||||
|
||||
// FindLatestStableRancherOS 安定版最新のRancherOSパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableRancherOS() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableRancherOSTags)
|
||||
}
|
||||
|
||||
// FindLatestStableKusanagi 安定版最新のKusanagiパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableKusanagi() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableKusanagiTags)
|
||||
}
|
||||
|
||||
// FindLatestStableSophosUTM 安定板最新のSophosUTMパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableSophosUTM() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableSophosUTMTags)
|
||||
}
|
||||
|
||||
// FindLatestStableFreeBSD 安定版最新のFreeBSDパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableFreeBSD() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableFreeBSDTags)
|
||||
}
|
||||
|
||||
// FindLatestStableWindows2012 安定版最新のWindows2012パブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableWindows2012() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableWindows2012Tags, map[string]interface{}{
|
||||
"Name": "Windows Server 2012 R2 Datacenter Edition",
|
||||
})
|
||||
}
|
||||
|
||||
// FindLatestStableWindows2012RDS 安定版最新のWindows2012RDSパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableWindows2012RDS() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableWindows2012RDSTags, map[string]interface{}{
|
||||
"Name": "Windows Server 2012 R2 for RDS",
|
||||
})
|
||||
}
|
||||
|
||||
// FindLatestStableWindows2012RDSOffice 安定版最新のWindows2012RDS(Office)パブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableWindows2012RDSOffice() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableWindows2012RDSOfficeTags, map[string]interface{}{
|
||||
"Name": "Windows Server 2012 R2 for RDS(MS Office付)",
|
||||
})
|
||||
}
|
||||
|
||||
// FindLatestStableWindows2016 安定版最新のWindows2016パブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableWindows2016() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableWindows2016Tags, map[string]interface{}{
|
||||
"Name": "Windows Server 2016 Datacenter Edition",
|
||||
})
|
||||
}
|
||||
|
||||
// FindLatestStableWindows2016RDS 安定版最新のWindows2016RDSパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableWindows2016RDS() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableWindows2016RDSTags, map[string]interface{}{
|
||||
"Name": "Windows Server 2016 for RDS",
|
||||
})
|
||||
}
|
||||
|
||||
// FindLatestStableWindows2016RDSOffice 安定版最新のWindows2016RDS(Office)パブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableWindows2016RDSOffice() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableWindows2016RDSOfficeTags, map[string]interface{}{
|
||||
"Name": "Windows Server 2016 for RDS(MS Office付)",
|
||||
})
|
||||
}
|
||||
|
||||
// FindLatestStableWindows2016SQLServerWeb 安定版最新のWindows2016 SQLServer(Web) パブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableWindows2016SQLServerWeb() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableWindows2016SQLServerWeb, map[string]interface{}{
|
||||
"Name": "Windows Server 2016 for MS SQL 2016(Web)",
|
||||
})
|
||||
}
|
||||
|
||||
// FindLatestStableWindows2016SQLServerStandard 安定版最新のWindows2016 SQLServer(Standard) パブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableWindows2016SQLServerStandard() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableWindows2016SQLServerStandard, map[string]interface{}{
|
||||
"Name": "Windows Server 2016 for MS SQL 2016(Standard)",
|
||||
})
|
||||
}
|
||||
|
||||
// FindLatestStableWindows2016SQLServerStandardAll 安定版最新のWindows2016 SQLServer(RDS+Office) パブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindLatestStableWindows2016SQLServerStandardAll() (*sacloud.Archive, error) {
|
||||
return api.findByOSTags(archiveLatestStableWindows2016SQLServerStandard, map[string]interface{}{
|
||||
"Name": "Windows Server 2016 for MS SQL 2016(Std) with RDS / MS Office",
|
||||
})
|
||||
}
|
||||
|
||||
// FindByOSType 指定のOS種別の安定版最新のパブリックアーカイブを取得
|
||||
func (api *ArchiveAPI) FindByOSType(os ostype.ArchiveOSTypes) (*sacloud.Archive, error) {
|
||||
if f, ok := api.findFuncMapPerOSType[os]; ok {
|
||||
return f()
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("OSType [%s] is invalid", os)
|
||||
}
|
||||
|
||||
func (api *ArchiveAPI) findByOSTags(tags []string, filterMap ...map[string]interface{}) (*sacloud.Archive, error) {
|
||||
|
||||
api.Reset().WithTags(tags)
|
||||
|
||||
for _, filters := range filterMap {
|
||||
for key, filter := range filters {
|
||||
api.FilterMultiBy(key, filter)
|
||||
}
|
||||
}
|
||||
res, err := api.Find()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Archive [%s] error : %s", strings.Join(tags, ","), err)
|
||||
}
|
||||
|
||||
if len(res.Archives) == 0 {
|
||||
return nil, fmt.Errorf("Archive [%s] Not Found", strings.Join(tags, ","))
|
||||
}
|
||||
|
||||
return &res.Archives[0], nil
|
||||
|
||||
}
|
251
vendor/github.com/sacloud/libsacloud/api/archive_gen.go
generated
vendored
Normal file
251
vendor/github.com/sacloud/libsacloud/api/archive_gen.go
generated
vendored
Normal file
@ -0,0 +1,251 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [ArchiveAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件リセット
|
||||
func (api *ArchiveAPI) Reset() *ArchiveAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *ArchiveAPI) Offset(offset int) *ArchiveAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *ArchiveAPI) Limit(limit int) *ArchiveAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *ArchiveAPI) Include(key string) *ArchiveAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *ArchiveAPI) Exclude(key string) *ArchiveAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 任意項目でのフィルタ(部分一致)
|
||||
func (api *ArchiveAPI) FilterBy(key string, value interface{}) *ArchiveAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ArchiveAPI) FilterMultiBy(key string, value interface{}) *ArchiveAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *ArchiveAPI) WithNameLike(name string) *ArchiveAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *ArchiveAPI) WithTag(tag string) *ArchiveAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *ArchiveAPI) WithTags(tags []string) *ArchiveAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// WithSizeGib アーカイブサイズ条件
|
||||
func (api *ArchiveAPI) WithSizeGib(size int) *ArchiveAPI {
|
||||
api.FilterBy("SizeMB", size*1024)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithSharedScope 共有スコープ条件
|
||||
func (api *ArchiveAPI) WithSharedScope() *ArchiveAPI {
|
||||
api.FilterBy("Scope", "shared")
|
||||
return api
|
||||
}
|
||||
|
||||
// WithUserScope ユーザースコープ条件
|
||||
func (api *ArchiveAPI) WithUserScope() *ArchiveAPI {
|
||||
api.FilterBy("Scope", "user")
|
||||
return api
|
||||
}
|
||||
|
||||
// SortBy 任意項目でのソート指定
|
||||
func (api *ArchiveAPI) SortBy(key string, reverse bool) *ArchiveAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *ArchiveAPI) SortByName(reverse bool) *ArchiveAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortBySize サイズでのソート
|
||||
func (api *ArchiveAPI) SortBySize(reverse bool) *ArchiveAPI {
|
||||
api.sortBy("SizeMB", reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interfaces for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件リセット
|
||||
func (api *ArchiveAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *ArchiveAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *ArchiveAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *ArchiveAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *ArchiveAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 任意項目でのフィルタ(部分一致)
|
||||
func (api *ArchiveAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ArchiveAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *ArchiveAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *ArchiveAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *ArchiveAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// SetSizeGib アーカイブサイズ条件
|
||||
func (api *ArchiveAPI) SetSizeGib(size int) {
|
||||
api.FilterBy("SizeMB", size*1024)
|
||||
}
|
||||
|
||||
// SetSharedScope 共有スコープ条件
|
||||
func (api *ArchiveAPI) SetSharedScope() {
|
||||
api.FilterBy("Scope", "shared")
|
||||
}
|
||||
|
||||
// SetUserScope ユーザースコープ条件
|
||||
func (api *ArchiveAPI) SetUserScope() {
|
||||
api.FilterBy("Scope", "user")
|
||||
}
|
||||
|
||||
// SetSortBy 任意項目でのソート指定
|
||||
func (api *ArchiveAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *ArchiveAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// SetSortBySize サイズでのソート
|
||||
func (api *ArchiveAPI) SetSortBySize(reverse bool) {
|
||||
api.sortBy("SizeMB", reverse)
|
||||
}
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// Create 新規作成
|
||||
func (api *ArchiveAPI) Create(value *sacloud.Archive) (*sacloud.Archive, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *ArchiveAPI) Read(id int64) (*sacloud.Archive, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *ArchiveAPI) Update(id int64, value *sacloud.Archive) (*sacloud.Archive, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *ArchiveAPI) Delete(id int64) (*sacloud.Archive, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// New 作成用パラメータ作成
|
||||
func (api *ArchiveAPI) New() *sacloud.Archive {
|
||||
return &sacloud.Archive{}
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *ArchiveAPI) setStateValue(setFunc func(*sacloud.Request)) *ArchiveAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *ArchiveAPI) request(f func(*sacloud.Response) error) (*sacloud.Archive, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Archive, nil
|
||||
}
|
||||
|
||||
func (api *ArchiveAPI) createRequest(value *sacloud.Archive) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.Archive = value
|
||||
return req
|
||||
}
|
42
vendor/github.com/sacloud/libsacloud/api/auth_status.go
generated
vendored
Normal file
42
vendor/github.com/sacloud/libsacloud/api/auth_status.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
// AuthStatusAPI 認証状態API
|
||||
type AuthStatusAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewAuthStatusAPI 認証状態API作成
|
||||
func NewAuthStatusAPI(client *Client) *AuthStatusAPI {
|
||||
return &AuthStatusAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "auth-status"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *AuthStatusAPI) Read() (*sacloud.AuthStatus, error) {
|
||||
|
||||
data, err := api.client.newRequest("GET", api.getResourceURL(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res sacloud.AuthStatus
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// Find 検索
|
||||
func (api *AuthStatusAPI) Find() (*sacloud.AuthStatus, error) {
|
||||
return api.Read()
|
||||
}
|
116
vendor/github.com/sacloud/libsacloud/api/auto_backup.go
generated
vendored
Normal file
116
vendor/github.com/sacloud/libsacloud/api/auto_backup.go
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
// "strings"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
// SearchAutoBackupResponse 自動バックアップ 検索レスポンス
|
||||
type SearchAutoBackupResponse struct {
|
||||
// Total 総件数
|
||||
Total int `json:",omitempty"`
|
||||
// From ページング開始位置
|
||||
From int `json:",omitempty"`
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// CommonServiceAutoBackupItems 自動バックアップ リスト
|
||||
CommonServiceAutoBackupItems []sacloud.AutoBackup `json:"CommonServiceItems,omitempty"`
|
||||
}
|
||||
|
||||
type autoBackupRequest struct {
|
||||
CommonServiceAutoBackupItem *sacloud.AutoBackup `json:"CommonServiceItem,omitempty"`
|
||||
From int `json:",omitempty"`
|
||||
Count int `json:",omitempty"`
|
||||
Sort []string `json:",omitempty"`
|
||||
Filter map[string]interface{} `json:",omitempty"`
|
||||
Exclude []string `json:",omitempty"`
|
||||
Include []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type autoBackupResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
*sacloud.AutoBackup `json:"CommonServiceItem,omitempty"`
|
||||
}
|
||||
|
||||
// AutoBackupAPI 自動バックアップAPI
|
||||
type AutoBackupAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewAutoBackupAPI 自動バックアップAPI作成
|
||||
func NewAutoBackupAPI(client *Client) *AutoBackupAPI {
|
||||
return &AutoBackupAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "commonserviceitem"
|
||||
},
|
||||
FuncBaseSearchCondition: func() *sacloud.Request {
|
||||
res := &sacloud.Request{}
|
||||
res.AddFilter("Provider.Class", "autobackup")
|
||||
return res
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Find 検索
|
||||
func (api *AutoBackupAPI) Find() (*SearchAutoBackupResponse, error) {
|
||||
|
||||
data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res SearchAutoBackupResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (api *AutoBackupAPI) request(f func(*autoBackupResponse) error) (*sacloud.AutoBackup, error) {
|
||||
res := &autoBackupResponse{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.AutoBackup, nil
|
||||
}
|
||||
|
||||
func (api *AutoBackupAPI) createRequest(value *sacloud.AutoBackup) *autoBackupResponse {
|
||||
return &autoBackupResponse{AutoBackup: value}
|
||||
}
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *AutoBackupAPI) New(name string, diskID int64) *sacloud.AutoBackup {
|
||||
return sacloud.CreateNewAutoBackup(name, diskID)
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *AutoBackupAPI) Create(value *sacloud.AutoBackup) (*sacloud.AutoBackup, error) {
|
||||
return api.request(func(res *autoBackupResponse) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *AutoBackupAPI) Read(id int64) (*sacloud.AutoBackup, error) {
|
||||
return api.request(func(res *autoBackupResponse) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *AutoBackupAPI) Update(id int64, value *sacloud.AutoBackup) (*sacloud.AutoBackup, error) {
|
||||
return api.request(func(res *autoBackupResponse) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *AutoBackupAPI) Delete(id int64) (*sacloud.AutoBackup, error) {
|
||||
return api.request(func(res *autoBackupResponse) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
239
vendor/github.com/sacloud/libsacloud/api/auto_backup_gen.go
generated
vendored
Normal file
239
vendor/github.com/sacloud/libsacloud/api/auto_backup_gen.go
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [AutoBackupAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件リセット
|
||||
func (api *AutoBackupAPI) Reset() *AutoBackupAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *AutoBackupAPI) Offset(offset int) *AutoBackupAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *AutoBackupAPI) Limit(limit int) *AutoBackupAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *AutoBackupAPI) Include(key string) *AutoBackupAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *AutoBackupAPI) Exclude(key string) *AutoBackupAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルタ
|
||||
func (api *AutoBackupAPI) FilterBy(key string, value interface{}) *AutoBackupAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *AutoBackupAPI) FilterMultiBy(key string, value interface{}) *AutoBackupAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *AutoBackupAPI) WithNameLike(name string) *AutoBackupAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *AutoBackupAPI) WithTag(tag string) *AutoBackupAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *AutoBackupAPI) WithTags(tags []string) *AutoBackupAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *AutoBackupAPI) WithSizeGib(size int) *AutoBackupAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *AutoBackupAPI) WithSharedScope() *AutoBackupAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *AutoBackupAPI) WithUserScope() *AutoBackupAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *AutoBackupAPI) SortBy(key string, reverse bool) *AutoBackupAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名前でのソート
|
||||
func (api *AutoBackupAPI) SortByName(reverse bool) *AutoBackupAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *AutoBackupAPI) SortBySize(reverse bool) *AutoBackupAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件リセット
|
||||
func (api *AutoBackupAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *AutoBackupAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *AutoBackupAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *AutoBackupAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *AutoBackupAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルタ
|
||||
func (api *AutoBackupAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *AutoBackupAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *AutoBackupAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *AutoBackupAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *AutoBackupAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *AutoBackupAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *AutoBackupAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *AutoBackupAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *AutoBackupAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名前でのソート
|
||||
func (api *AutoBackupAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *AutoBackupAPI) SortBySize(reverse bool) *AutoBackupAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *AutoBackupAPI) New() *sacloud.AutoBackup {
|
||||
// return &sacloud.AutoBackup{}
|
||||
// }
|
||||
|
||||
// func (api *AutoBackupAPI) Create(value *sacloud.AutoBackup) (*sacloud.AutoBackup, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *AutoBackupAPI) Read(id string) (*sacloud.AutoBackup, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *AutoBackupAPI) Update(id string, value *sacloud.AutoBackup) (*sacloud.AutoBackup, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *AutoBackupAPI) Delete(id string) (*sacloud.AutoBackup, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *AutoBackupAPI) setStateValue(setFunc func(*sacloud.Request)) *AutoBackupAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *AutoBackupAPI) request(f func(*sacloud.Response) error) (*sacloud.AutoBackup, error) {
|
||||
// res := &sacloud.Response{}
|
||||
// err := f(res)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return res.AutoBackup, nil
|
||||
//}
|
||||
//
|
||||
//func (api *AutoBackupAPI) createRequest(value *sacloud.AutoBackup) *sacloud.Request {
|
||||
// req := &sacloud.Request{}
|
||||
// req.AutoBackup = value
|
||||
// return req
|
||||
//}
|
277
vendor/github.com/sacloud/libsacloud/api/base_api.go
generated
vendored
Normal file
277
vendor/github.com/sacloud/libsacloud/api/base_api.go
generated
vendored
Normal file
@ -0,0 +1,277 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type baseAPI struct {
|
||||
client *Client
|
||||
FuncGetResourceURL func() string
|
||||
FuncBaseSearchCondition func() *sacloud.Request
|
||||
state *sacloud.Request
|
||||
apiRootSuffix string
|
||||
}
|
||||
|
||||
var (
|
||||
sakuraCloudAPIRootSuffix = "api/cloud/1.1"
|
||||
sakuraBillingAPIRootSuffix = "api/system/1.0"
|
||||
sakuraWebAccelAPIRootSuffix = "api/webaccel/1.0"
|
||||
)
|
||||
|
||||
func (api *baseAPI) getResourceURL() string {
|
||||
|
||||
suffix := api.apiRootSuffix
|
||||
//デフォルト : クラウドAPI
|
||||
if suffix == "" {
|
||||
suffix = sakuraCloudAPIRootSuffix
|
||||
}
|
||||
|
||||
url := ""
|
||||
if api.FuncGetResourceURL != nil {
|
||||
url = api.FuncGetResourceURL()
|
||||
}
|
||||
|
||||
if suffix == "" {
|
||||
return url
|
||||
}
|
||||
if url == "" {
|
||||
return suffix
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s", suffix, url)
|
||||
}
|
||||
|
||||
func (api *baseAPI) getSearchState() *sacloud.Request {
|
||||
if api.state == nil {
|
||||
api.reset()
|
||||
}
|
||||
return api.state
|
||||
}
|
||||
func (api *baseAPI) sortBy(key string, reverse bool) *baseAPI {
|
||||
return api.setStateValue(func(state *sacloud.Request) {
|
||||
if state.Sort == nil {
|
||||
state.Sort = []string{}
|
||||
}
|
||||
|
||||
col := key
|
||||
if reverse {
|
||||
col = "-" + col
|
||||
}
|
||||
state.Sort = append(state.Sort, col)
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (api *baseAPI) reset() *baseAPI {
|
||||
if api.FuncBaseSearchCondition == nil {
|
||||
api.state = &sacloud.Request{}
|
||||
} else {
|
||||
api.state = api.FuncBaseSearchCondition()
|
||||
}
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *baseAPI) setStateValue(setFunc func(*sacloud.Request)) *baseAPI {
|
||||
state := api.getSearchState()
|
||||
setFunc(state)
|
||||
return api
|
||||
|
||||
}
|
||||
|
||||
func (api *baseAPI) offset(offset int) *baseAPI {
|
||||
return api.setStateValue(func(state *sacloud.Request) {
|
||||
state.From = offset
|
||||
})
|
||||
}
|
||||
|
||||
func (api *baseAPI) limit(limit int) *baseAPI {
|
||||
return api.setStateValue(func(state *sacloud.Request) {
|
||||
state.Count = limit
|
||||
})
|
||||
}
|
||||
|
||||
func (api *baseAPI) include(key string) *baseAPI {
|
||||
return api.setStateValue(func(state *sacloud.Request) {
|
||||
if state.Include == nil {
|
||||
state.Include = []string{}
|
||||
}
|
||||
state.Include = append(state.Include, key)
|
||||
})
|
||||
}
|
||||
|
||||
func (api *baseAPI) exclude(key string) *baseAPI {
|
||||
return api.setStateValue(func(state *sacloud.Request) {
|
||||
if state.Exclude == nil {
|
||||
state.Exclude = []string{}
|
||||
}
|
||||
state.Exclude = append(state.Exclude, key)
|
||||
})
|
||||
}
|
||||
|
||||
func (api *baseAPI) filterBy(key string, value interface{}, multiple bool) *baseAPI {
|
||||
return api.setStateValue(func(state *sacloud.Request) {
|
||||
|
||||
//HACK さくらのクラウド側でqueryStringでの+エスケープに対応していないため、
|
||||
// %20にエスケープされるurl.Pathを利用する。
|
||||
// http://qiita.com/shibukawa/items/c0730092371c0e243f62
|
||||
if strValue, ok := value.(string); ok {
|
||||
u := &url.URL{Path: strValue}
|
||||
value = u.String()
|
||||
}
|
||||
|
||||
if state.Filter == nil {
|
||||
state.Filter = map[string]interface{}{}
|
||||
}
|
||||
if multiple {
|
||||
if state.Filter[key] == nil {
|
||||
state.Filter[key] = []interface{}{}
|
||||
}
|
||||
|
||||
state.Filter[key] = append(state.Filter[key].([]interface{}), value)
|
||||
} else {
|
||||
// どちらもstring型の場合はスペース区切りで繋げる
|
||||
if f, ok := state.Filter[key]; ok {
|
||||
if s, ok := f.(string); ok && s != "" {
|
||||
if v, ok := value.(string); ok {
|
||||
state.Filter[key] = fmt.Sprintf("%s %s", s, v)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
state.Filter[key] = value
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (api *baseAPI) withNameLike(name string) *baseAPI {
|
||||
return api.filterBy("Name", name, false)
|
||||
}
|
||||
|
||||
func (api *baseAPI) withTag(tag string) *baseAPI {
|
||||
return api.filterBy("Tags.Name", tag, false)
|
||||
}
|
||||
|
||||
func (api *baseAPI) withTags(tags []string) *baseAPI {
|
||||
return api.filterBy("Tags.Name", tags, false)
|
||||
}
|
||||
|
||||
func (api *baseAPI) sortByName(reverse bool) *baseAPI {
|
||||
return api.sortBy("Name", reverse)
|
||||
}
|
||||
|
||||
func (api *baseAPI) Find() (*sacloud.SearchResponse, error) {
|
||||
|
||||
data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res sacloud.SearchResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (api *baseAPI) request(method string, uri string, body interface{}, res interface{}) error {
|
||||
data, err := api.client.newRequest(method, uri, body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if res != nil {
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (api *baseAPI) create(body interface{}, res interface{}) error {
|
||||
var (
|
||||
method = "POST"
|
||||
uri = api.getResourceURL()
|
||||
)
|
||||
|
||||
return api.request(method, uri, body, res)
|
||||
}
|
||||
|
||||
func (api *baseAPI) read(id int64, body interface{}, res interface{}) error {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.request(method, uri, body, res)
|
||||
}
|
||||
|
||||
func (api *baseAPI) update(id int64, body interface{}, res interface{}) error {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d", api.getResourceURL(), id)
|
||||
)
|
||||
return api.request(method, uri, body, res)
|
||||
}
|
||||
|
||||
func (api *baseAPI) delete(id int64, body interface{}, res interface{}) error {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d", api.getResourceURL(), id)
|
||||
)
|
||||
return api.request(method, uri, body, res)
|
||||
}
|
||||
|
||||
func (api *baseAPI) modify(method string, uri string, body interface{}) (bool, error) {
|
||||
res := &sacloud.ResultFlagValue{}
|
||||
err := api.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return res.IsOk, nil
|
||||
}
|
||||
|
||||
func (api *baseAPI) action(method string, uri string, body interface{}, res interface{}) (bool, error) {
|
||||
err := api.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (api *baseAPI) monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/monitor", api.getResourceURL(), id)
|
||||
)
|
||||
res := &sacloud.ResourceMonitorResponse{}
|
||||
err := api.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Data, nil
|
||||
}
|
||||
|
||||
func (api *baseAPI) applianceMonitorBy(id int64, target string, nicIndex int, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/%s/%d/monitor", api.getResourceURL(), id, target, nicIndex)
|
||||
)
|
||||
if nicIndex == 0 {
|
||||
uri = fmt.Sprintf("%s/%d/%s/monitor", api.getResourceURL(), id, target)
|
||||
}
|
||||
|
||||
res := &sacloud.ResourceMonitorResponse{}
|
||||
err := api.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Data, nil
|
||||
}
|
||||
|
||||
func (api *baseAPI) NewResourceMonitorRequest() *sacloud.ResourceMonitorRequest {
|
||||
return &sacloud.ResourceMonitorRequest{}
|
||||
}
|
185
vendor/github.com/sacloud/libsacloud/api/bill.go
generated
vendored
Normal file
185
vendor/github.com/sacloud/libsacloud/api/bill.go
generated
vendored
Normal file
@ -0,0 +1,185 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BillAPI 請求情報API
|
||||
type BillAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewBillAPI 請求情報API作成
|
||||
func NewBillAPI(client *Client) *BillAPI {
|
||||
return &BillAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
apiRootSuffix: sakuraBillingAPIRootSuffix,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "bill"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// BillResponse 請求情報レスポンス
|
||||
type BillResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// ResponsedAt 応答日時
|
||||
ResponsedAt *time.Time `json:",omitempty"`
|
||||
// Bills 請求情報 リスト
|
||||
Bills []*sacloud.Bill
|
||||
}
|
||||
|
||||
// BillDetailResponse 請求明細レスポンス
|
||||
type BillDetailResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// ResponsedAt 応答日時
|
||||
ResponsedAt *time.Time `json:",omitempty"`
|
||||
// BillDetails 請求明細 リスト
|
||||
BillDetails []*sacloud.BillDetail
|
||||
}
|
||||
|
||||
// BillDetailCSVResponse 請求明細CSVレスポンス
|
||||
type BillDetailCSVResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// ResponsedAt 応答日時
|
||||
ResponsedAt *time.Time `json:",omitempty"`
|
||||
// Filename ファイル名
|
||||
Filename string `json:",omitempty"`
|
||||
// RawBody ボディ(未加工)
|
||||
RawBody string `json:"Body,omitempty"`
|
||||
// HeaderRow ヘッダ行
|
||||
HeaderRow []string
|
||||
// BodyRows ボディ(各行/各列での配列)
|
||||
BodyRows [][]string
|
||||
}
|
||||
|
||||
func (res *BillDetailCSVResponse) buildCSVBody() {
|
||||
|
||||
if res == nil || res.RawBody == "" {
|
||||
return
|
||||
}
|
||||
|
||||
//CSV分割(先頭行/それ以降)、
|
||||
reader := csv.NewReader(strings.NewReader(res.RawBody))
|
||||
reader.LazyQuotes = true
|
||||
|
||||
isFirst := true
|
||||
res.BodyRows = [][]string{}
|
||||
for {
|
||||
record, err := reader.Read()
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if isFirst {
|
||||
res.HeaderRow = record
|
||||
isFirst = false
|
||||
} else {
|
||||
res.BodyRows = append(res.BodyRows, record)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ByContract アカウントIDごとの請求取得
|
||||
func (api *BillAPI) ByContract(accountID int64) (*BillResponse, error) {
|
||||
|
||||
uri := fmt.Sprintf("%s/by-contract/%d", api.getResourceURL(), accountID)
|
||||
return api.getContract(uri)
|
||||
}
|
||||
|
||||
// ByContractYear 年指定での請求取得
|
||||
func (api *BillAPI) ByContractYear(accountID int64, year int) (*BillResponse, error) {
|
||||
uri := fmt.Sprintf("%s/by-contract/%d/%d", api.getResourceURL(), accountID, year)
|
||||
return api.getContract(uri)
|
||||
}
|
||||
|
||||
// ByContractYearMonth 年月指定での請求指定
|
||||
func (api *BillAPI) ByContractYearMonth(accountID int64, year int, month int) (*BillResponse, error) {
|
||||
uri := fmt.Sprintf("%s/by-contract/%d/%d/%d", api.getResourceURL(), accountID, year, month)
|
||||
return api.getContract(uri)
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *BillAPI) Read(billNo int64) (*BillResponse, error) {
|
||||
uri := fmt.Sprintf("%s/id/%d/", api.getResourceURL(), billNo)
|
||||
return api.getContract(uri)
|
||||
|
||||
}
|
||||
|
||||
func (api *BillAPI) getContract(uri string) (*BillResponse, error) {
|
||||
|
||||
data, err := api.client.newRequest("GET", uri, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res BillResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
|
||||
}
|
||||
|
||||
// GetDetail 請求明細取得
|
||||
func (api *BillAPI) GetDetail(memberCD string, billNo int64) (*BillDetailResponse, error) {
|
||||
|
||||
oldFunc := api.FuncGetResourceURL
|
||||
defer func() { api.FuncGetResourceURL = oldFunc }()
|
||||
api.FuncGetResourceURL = func() string {
|
||||
return "billdetail"
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s/%s/%d", api.getResourceURL(), memberCD, billNo)
|
||||
data, err := api.client.newRequest("GET", uri, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res BillDetailResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
|
||||
}
|
||||
|
||||
// GetDetailCSV 請求明細CSV取得
|
||||
func (api *BillAPI) GetDetailCSV(memberCD string, billNo int64) (*BillDetailCSVResponse, error) {
|
||||
|
||||
oldFunc := api.FuncGetResourceURL
|
||||
defer func() { api.FuncGetResourceURL = oldFunc }()
|
||||
api.FuncGetResourceURL = func() string {
|
||||
return "billdetail"
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s/%s/%d/csv", api.getResourceURL(), memberCD, billNo)
|
||||
data, err := api.client.newRequest("GET", uri, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res BillDetailCSVResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// build HeaderRow and BodyRows from RawBody
|
||||
res.buildCSVBody()
|
||||
|
||||
return &res, nil
|
||||
|
||||
}
|
18
vendor/github.com/sacloud/libsacloud/api/bridge.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/bridge.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// BridgeAPI ブリッジAPI
|
||||
type BridgeAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewBridgeAPI ブリッジAPI作成
|
||||
func NewBridgeAPI(client *Client) *BridgeAPI {
|
||||
return &BridgeAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "bridge"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
243
vendor/github.com/sacloud/libsacloud/api/bridge_gen.go
generated
vendored
Normal file
243
vendor/github.com/sacloud/libsacloud/api/bridge_gen.go
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [BridgeAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件リセット
|
||||
func (api *BridgeAPI) Reset() *BridgeAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *BridgeAPI) Offset(offset int) *BridgeAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *BridgeAPI) Limit(limit int) *BridgeAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *BridgeAPI) Include(key string) *BridgeAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *BridgeAPI) Exclude(key string) *BridgeAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *BridgeAPI) FilterBy(key string, value interface{}) *BridgeAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *BridgeAPI) FilterMultiBy(key string, value interface{}) *BridgeAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *BridgeAPI) WithNameLike(name string) *BridgeAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *BridgeAPI) WithTag(tag string) *BridgeAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *BridgeAPI) WithTags(tags []string) *BridgeAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *BridgeAPI) WithSizeGib(size int) *BridgeAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *BridgeAPI) WithSharedScope() *BridgeAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *BridgeAPI) WithUserScope() *BridgeAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *BridgeAPI) SortBy(key string, reverse bool) *BridgeAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *BridgeAPI) SortByName(reverse bool) *BridgeAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *BridgeAPI) SortBySize(reverse bool) *BridgeAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件リセット
|
||||
func (api *BridgeAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *BridgeAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *BridgeAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *BridgeAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *BridgeAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *BridgeAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *BridgeAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *BridgeAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *BridgeAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *BridgeAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *BridgeAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *BridgeAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *BridgeAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *BridgeAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *BridgeAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *BridgeAPI) SortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *BridgeAPI) New() *sacloud.Bridge {
|
||||
return &sacloud.Bridge{}
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *BridgeAPI) Create(value *sacloud.Bridge) (*sacloud.Bridge, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *BridgeAPI) Read(id int64) (*sacloud.Bridge, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *BridgeAPI) Update(id int64, value *sacloud.Bridge) (*sacloud.Bridge, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *BridgeAPI) Delete(id int64) (*sacloud.Bridge, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *BridgeAPI) setStateValue(setFunc func(*sacloud.Request)) *BridgeAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *BridgeAPI) request(f func(*sacloud.Response) error) (*sacloud.Bridge, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Bridge, nil
|
||||
}
|
||||
|
||||
func (api *BridgeAPI) createRequest(value *sacloud.Bridge) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.Bridge = value
|
||||
return req
|
||||
}
|
80
vendor/github.com/sacloud/libsacloud/api/cdrom.go
generated
vendored
Normal file
80
vendor/github.com/sacloud/libsacloud/api/cdrom.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CDROMAPI ISOイメージAPI
|
||||
type CDROMAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewCDROMAPI ISOイメージAPI新規作成
|
||||
func NewCDROMAPI(client *Client) *CDROMAPI {
|
||||
return &CDROMAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "cdrom"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *CDROMAPI) Create(value *sacloud.CDROM) (*sacloud.CDROM, *sacloud.FTPServer, error) {
|
||||
f := func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
}
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return res.CDROM, res.FTPServer, nil
|
||||
}
|
||||
|
||||
// OpenFTP FTP接続開始
|
||||
func (api *CDROMAPI) OpenFTP(id int64, reset bool) (*sacloud.FTPServer, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/ftp", api.getResourceURL(), id)
|
||||
body = map[string]bool{"ChangePassword": reset}
|
||||
res = &sacloud.Response{}
|
||||
)
|
||||
|
||||
result, err := api.action(method, uri, body, res)
|
||||
if !result || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.FTPServer, nil
|
||||
}
|
||||
|
||||
// CloseFTP FTP接続終了
|
||||
func (api *CDROMAPI) CloseFTP(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/ftp", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
|
||||
}
|
||||
|
||||
// SleepWhileCopying コピー終了まで待機
|
||||
func (api *CDROMAPI) SleepWhileCopying(id int64, timeout time.Duration) error {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// AsyncSleepWhileCopying コピー終了まで待機(非同期)
|
||||
func (api *CDROMAPI) AsyncSleepWhileCopying(id int64, timeout time.Duration) (chan (interface{}), chan (interface{}), chan (error)) {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return poll(handler, timeout)
|
||||
}
|
250
vendor/github.com/sacloud/libsacloud/api/cdrom_gen.go
generated
vendored
Normal file
250
vendor/github.com/sacloud/libsacloud/api/cdrom_gen.go
generated
vendored
Normal file
@ -0,0 +1,250 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [CDROMAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件リセット
|
||||
func (api *CDROMAPI) Reset() *CDROMAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *CDROMAPI) Offset(offset int) *CDROMAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *CDROMAPI) Limit(limit int) *CDROMAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *CDROMAPI) Include(key string) *CDROMAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *CDROMAPI) Exclude(key string) *CDROMAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *CDROMAPI) FilterBy(key string, value interface{}) *CDROMAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *CDROMAPI) FilterMultiBy(key string, value interface{}) *CDROMAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *CDROMAPI) WithNameLike(name string) *CDROMAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *CDROMAPI) WithTag(tag string) *CDROMAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *CDROMAPI) WithTags(tags []string) *CDROMAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// WithSizeGib サイズ条件
|
||||
func (api *CDROMAPI) WithSizeGib(size int) *CDROMAPI {
|
||||
api.FilterBy("SizeMB", size*1024)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithSharedScope 公開スコープ条件
|
||||
func (api *CDROMAPI) WithSharedScope() *CDROMAPI {
|
||||
api.FilterBy("Scope", "shared")
|
||||
return api
|
||||
}
|
||||
|
||||
// WithUserScope ユーザースコープ条件
|
||||
func (api *CDROMAPI) WithUserScope() *CDROMAPI {
|
||||
api.FilterBy("Scope", "user")
|
||||
return api
|
||||
}
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *CDROMAPI) SortBy(key string, reverse bool) *CDROMAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *CDROMAPI) SortByName(reverse bool) *CDROMAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortBySize サイズでのソート
|
||||
func (api *CDROMAPI) SortBySize(reverse bool) *CDROMAPI {
|
||||
api.sortBy("SizeMB", reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件リセット
|
||||
func (api *CDROMAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *CDROMAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *CDROMAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *CDROMAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *CDROMAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *CDROMAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *CDROMAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *CDROMAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *CDROMAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *CDROMAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// SetSizeGib サイズ条件
|
||||
func (api *CDROMAPI) SetSizeGib(size int) {
|
||||
api.FilterBy("SizeMB", size*1024)
|
||||
}
|
||||
|
||||
// SetSharedScope 公開スコープ条件
|
||||
func (api *CDROMAPI) SetSharedScope() {
|
||||
api.FilterBy("Scope", "shared")
|
||||
}
|
||||
|
||||
// SetUserScope ユーザースコープ条件
|
||||
func (api *CDROMAPI) SetUserScope() {
|
||||
api.FilterBy("Scope", "user")
|
||||
}
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *CDROMAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *CDROMAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// SetSortBySize サイズでのソート
|
||||
func (api *CDROMAPI) SetSortBySize(reverse bool) {
|
||||
api.sortBy("SizeMB", reverse)
|
||||
}
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメータ作成
|
||||
func (api *CDROMAPI) New() *sacloud.CDROM {
|
||||
return &sacloud.CDROM{}
|
||||
}
|
||||
|
||||
//func (api *CDROMAPI) Create(value *sacloud.CDROM) (*sacloud.CDROM, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
//}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *CDROMAPI) Read(id int64) (*sacloud.CDROM, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *CDROMAPI) Update(id int64, value *sacloud.CDROM) (*sacloud.CDROM, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *CDROMAPI) Delete(id int64) (*sacloud.CDROM, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *CDROMAPI) setStateValue(setFunc func(*sacloud.Request)) *CDROMAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *CDROMAPI) request(f func(*sacloud.Response) error) (*sacloud.CDROM, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.CDROM, nil
|
||||
}
|
||||
|
||||
func (api *CDROMAPI) createRequest(value *sacloud.CDROM) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.CDROM = value
|
||||
return req
|
||||
}
|
608
vendor/github.com/sacloud/libsacloud/api/client.go
generated
vendored
Normal file
608
vendor/github.com/sacloud/libsacloud/api/client.go
generated
vendored
Normal file
@ -0,0 +1,608 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// SakuraCloudAPIRoot APIリクエスト送信先ルートURL(末尾にスラッシュを含まない)
|
||||
SakuraCloudAPIRoot = "https://secure.sakura.ad.jp/cloud/zone"
|
||||
)
|
||||
|
||||
// Client APIクライアント
|
||||
type Client struct {
|
||||
// AccessToken アクセストークン
|
||||
AccessToken string
|
||||
// AccessTokenSecret アクセストークンシークレット
|
||||
AccessTokenSecret string
|
||||
// Zone 対象ゾーン
|
||||
Zone string
|
||||
*API
|
||||
// TraceMode トレースモード
|
||||
TraceMode bool
|
||||
// DefaultTimeoutDuration デフォルトタイムアウト間隔
|
||||
DefaultTimeoutDuration time.Duration
|
||||
// ユーザーエージェント
|
||||
UserAgent string
|
||||
// Accept-Language
|
||||
AcceptLanguage string
|
||||
// リクエストパラメーター トレーサー
|
||||
RequestTracer io.Writer
|
||||
// レスポンス トレーサー
|
||||
ResponseTracer io.Writer
|
||||
// 503エラー時のリトライ回数
|
||||
RetryMax int
|
||||
// 503エラー時のリトライ待ち時間
|
||||
RetryInterval time.Duration
|
||||
}
|
||||
|
||||
// NewClient APIクライアント作成
|
||||
func NewClient(token, tokenSecret, zone string) *Client {
|
||||
c := &Client{
|
||||
AccessToken: token,
|
||||
AccessTokenSecret: tokenSecret,
|
||||
Zone: zone,
|
||||
TraceMode: false,
|
||||
DefaultTimeoutDuration: 20 * time.Minute,
|
||||
UserAgent: fmt.Sprintf("libsacloud/%s", libsacloud.Version),
|
||||
AcceptLanguage: "",
|
||||
RetryMax: 0,
|
||||
RetryInterval: 5 * time.Second,
|
||||
}
|
||||
c.API = newAPI(c)
|
||||
return c
|
||||
}
|
||||
|
||||
// Clone APIクライアント クローン作成
|
||||
func (c *Client) Clone() *Client {
|
||||
n := &Client{
|
||||
AccessToken: c.AccessToken,
|
||||
AccessTokenSecret: c.AccessTokenSecret,
|
||||
Zone: c.Zone,
|
||||
TraceMode: c.TraceMode,
|
||||
DefaultTimeoutDuration: c.DefaultTimeoutDuration,
|
||||
UserAgent: c.UserAgent,
|
||||
AcceptLanguage: c.AcceptLanguage,
|
||||
RetryMax: c.RetryMax,
|
||||
RetryInterval: c.RetryInterval,
|
||||
}
|
||||
n.API = newAPI(n)
|
||||
return n
|
||||
}
|
||||
|
||||
func (c *Client) getEndpoint() string {
|
||||
return fmt.Sprintf("%s/%s", SakuraCloudAPIRoot, c.Zone)
|
||||
}
|
||||
|
||||
func (c *Client) isOkStatus(code int) bool {
|
||||
codes := map[int]bool{
|
||||
200: true,
|
||||
201: true,
|
||||
202: true,
|
||||
204: true,
|
||||
305: false,
|
||||
400: false,
|
||||
401: false,
|
||||
403: false,
|
||||
404: false,
|
||||
405: false,
|
||||
406: false,
|
||||
408: false,
|
||||
409: false,
|
||||
411: false,
|
||||
413: false,
|
||||
415: false,
|
||||
500: false,
|
||||
503: false,
|
||||
}
|
||||
return codes[code]
|
||||
}
|
||||
|
||||
func (c *Client) newRequest(method, uri string, body interface{}) ([]byte, error) {
|
||||
var (
|
||||
client = &retryableHTTPClient{
|
||||
retryMax: c.RetryMax,
|
||||
retryInterval: c.RetryInterval,
|
||||
}
|
||||
err error
|
||||
req *request
|
||||
)
|
||||
var url = uri
|
||||
if !strings.HasPrefix(url, "https://") {
|
||||
url = fmt.Sprintf("%s/%s", c.getEndpoint(), uri)
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
var bodyJSON []byte
|
||||
bodyJSON, err = json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if method == "GET" {
|
||||
url = fmt.Sprintf("%s?%s", url, bytes.NewBuffer(bodyJSON))
|
||||
req, err = newRequest(method, url, nil)
|
||||
} else {
|
||||
req, err = newRequest(method, url, bytes.NewReader(bodyJSON))
|
||||
}
|
||||
b, _ := json.MarshalIndent(body, "", "\t")
|
||||
if c.TraceMode {
|
||||
log.Printf("[libsacloud:Client#request] method : %#v , url : %s , \nbody : %s", method, url, b)
|
||||
}
|
||||
if c.RequestTracer != nil {
|
||||
c.RequestTracer.Write(b)
|
||||
}
|
||||
} else {
|
||||
req, err = newRequest(method, url, nil)
|
||||
if c.TraceMode {
|
||||
log.Printf("[libsacloud:Client#request] method : %#v , url : %s ", method, url)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error with request: %v - %q", url, err)
|
||||
}
|
||||
|
||||
req.SetBasicAuth(c.AccessToken, c.AccessTokenSecret)
|
||||
req.Header.Add("X-Sakura-Bigint-As-Int", "1") //Use BigInt on resource ids.
|
||||
//if c.TraceMode {
|
||||
// req.Header.Add("X-Sakura-API-Beautify", "1") // format response-JSON
|
||||
//}
|
||||
req.Header.Add("User-Agent", c.UserAgent)
|
||||
if c.AcceptLanguage != "" {
|
||||
req.Header.Add("Accept-Language", c.AcceptLanguage)
|
||||
}
|
||||
req.Method = method
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
v := &map[string]interface{}{}
|
||||
json.Unmarshal(data, v)
|
||||
b, _ := json.MarshalIndent(v, "", "\t")
|
||||
if c.ResponseTracer != nil {
|
||||
c.ResponseTracer.Write(b)
|
||||
}
|
||||
|
||||
if c.TraceMode {
|
||||
log.Printf("[libsacloud:Client#response] : %s", b)
|
||||
}
|
||||
if !c.isOkStatus(resp.StatusCode) {
|
||||
|
||||
errResponse := &sacloud.ResultErrorValue{}
|
||||
err := json.Unmarshal(data, errResponse)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error in response: %s", string(data))
|
||||
}
|
||||
return nil, NewError(resp.StatusCode, errResponse)
|
||||
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
type lenReader interface {
|
||||
Len() int
|
||||
}
|
||||
|
||||
type request struct {
|
||||
// body is a seekable reader over the request body payload. This is
|
||||
// used to rewind the request data in between retries.
|
||||
body io.ReadSeeker
|
||||
|
||||
// Embed an HTTP request directly. This makes a *Request act exactly
|
||||
// like an *http.Request so that all meta methods are supported.
|
||||
*http.Request
|
||||
}
|
||||
|
||||
func newRequest(method, url string, body io.ReadSeeker) (*request, error) {
|
||||
var rcBody io.ReadCloser
|
||||
if body != nil {
|
||||
rcBody = ioutil.NopCloser(body)
|
||||
}
|
||||
|
||||
httpReq, err := http.NewRequest(method, url, rcBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if lr, ok := body.(lenReader); ok {
|
||||
httpReq.ContentLength = int64(lr.Len())
|
||||
}
|
||||
|
||||
return &request{body, httpReq}, nil
|
||||
}
|
||||
|
||||
type retryableHTTPClient struct {
|
||||
http.Client
|
||||
retryInterval time.Duration
|
||||
retryMax int
|
||||
}
|
||||
|
||||
func (c *retryableHTTPClient) Do(req *request) (*http.Response, error) {
|
||||
for i := 0; ; i++ {
|
||||
|
||||
if req.body != nil {
|
||||
if _, err := req.body.Seek(0, 0); err != nil {
|
||||
return nil, fmt.Errorf("failed to seek body: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
res, err := c.Client.Do(req.Request)
|
||||
if res != nil && res.StatusCode != 503 {
|
||||
return res, err
|
||||
}
|
||||
if res != nil && res.Body != nil {
|
||||
res.Body.Close()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
remain := c.retryMax - i
|
||||
if remain == 0 {
|
||||
break
|
||||
}
|
||||
time.Sleep(c.retryInterval)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%s %s giving up after %d attempts",
|
||||
req.Method, req.URL, c.retryMax+1)
|
||||
}
|
||||
|
||||
// API libsacloudでサポートしているAPI群
|
||||
type API struct {
|
||||
AuthStatus *AuthStatusAPI // 認証状態API
|
||||
AutoBackup *AutoBackupAPI // 自動バックアップAPI
|
||||
Archive *ArchiveAPI // アーカイブAPI
|
||||
Bill *BillAPI // 請求情報API
|
||||
Bridge *BridgeAPI // ブリッジAPi
|
||||
CDROM *CDROMAPI // ISOイメージAPI
|
||||
Database *DatabaseAPI // データベースAPI
|
||||
Disk *DiskAPI // ディスクAPI
|
||||
DNS *DNSAPI // DNS API
|
||||
Facility *FacilityAPI // ファシリティAPI
|
||||
GSLB *GSLBAPI // GSLB API
|
||||
Icon *IconAPI // アイコンAPI
|
||||
Interface *InterfaceAPI // インターフェースAPI
|
||||
Internet *InternetAPI // ルーターAPI
|
||||
IPAddress *IPAddressAPI // IPアドレスAPI
|
||||
IPv6Addr *IPv6AddrAPI // IPv6アドレスAPI
|
||||
IPv6Net *IPv6NetAPI // IPv6ネットワークAPI
|
||||
License *LicenseAPI // ライセンスAPI
|
||||
LoadBalancer *LoadBalancerAPI // ロードバランサーAPI
|
||||
MobileGateway *MobileGatewayAPI // モバイルゲートウェイAPI
|
||||
NewsFeed *NewsFeedAPI // フィード(障害/メンテナンス情報)API
|
||||
NFS *NFSAPI // NFS API
|
||||
Note *NoteAPI // スタートアップスクリプトAPI
|
||||
PacketFilter *PacketFilterAPI // パケットフィルタAPI
|
||||
PrivateHost *PrivateHostAPI // 専有ホストAPI
|
||||
Product *ProductAPI // 製品情報API
|
||||
Server *ServerAPI // サーバーAPI
|
||||
SIM *SIMAPI // SIM API
|
||||
SimpleMonitor *SimpleMonitorAPI // シンプル監視API
|
||||
SSHKey *SSHKeyAPI // 公開鍵API
|
||||
Subnet *SubnetAPI // IPv4ネットワークAPI
|
||||
Switch *SwitchAPI // スイッチAPI
|
||||
VPCRouter *VPCRouterAPI // VPCルーターAPI
|
||||
WebAccel *WebAccelAPI // ウェブアクセラレータAPI
|
||||
}
|
||||
|
||||
// GetAuthStatusAPI 認証状態API取得
|
||||
func (api *API) GetAuthStatusAPI() *AuthStatusAPI {
|
||||
return api.AuthStatus
|
||||
}
|
||||
|
||||
// GetAutoBackupAPI 自動バックアップAPI取得
|
||||
func (api *API) GetAutoBackupAPI() *AutoBackupAPI {
|
||||
return api.AutoBackup
|
||||
}
|
||||
|
||||
// GetArchiveAPI アーカイブAPI取得
|
||||
func (api *API) GetArchiveAPI() *ArchiveAPI {
|
||||
return api.Archive
|
||||
}
|
||||
|
||||
// GetBillAPI 請求情報API取得
|
||||
func (api *API) GetBillAPI() *BillAPI {
|
||||
return api.Bill
|
||||
}
|
||||
|
||||
// GetBridgeAPI ブリッジAPI取得
|
||||
func (api *API) GetBridgeAPI() *BridgeAPI {
|
||||
return api.Bridge
|
||||
}
|
||||
|
||||
// GetCDROMAPI ISOイメージAPI取得
|
||||
func (api *API) GetCDROMAPI() *CDROMAPI {
|
||||
return api.CDROM
|
||||
}
|
||||
|
||||
// GetDatabaseAPI データベースAPI取得
|
||||
func (api *API) GetDatabaseAPI() *DatabaseAPI {
|
||||
return api.Database
|
||||
}
|
||||
|
||||
// GetDiskAPI ディスクAPI取得
|
||||
func (api *API) GetDiskAPI() *DiskAPI {
|
||||
return api.Disk
|
||||
}
|
||||
|
||||
// GetDNSAPI DNSAPI取得
|
||||
func (api *API) GetDNSAPI() *DNSAPI {
|
||||
return api.DNS
|
||||
}
|
||||
|
||||
// GetRegionAPI リージョンAPI取得
|
||||
func (api *API) GetRegionAPI() *RegionAPI {
|
||||
return api.Facility.GetRegionAPI()
|
||||
}
|
||||
|
||||
// GetZoneAPI ゾーンAPI取得
|
||||
func (api *API) GetZoneAPI() *ZoneAPI {
|
||||
return api.Facility.GetZoneAPI()
|
||||
}
|
||||
|
||||
// GetGSLBAPI GSLB API取得
|
||||
func (api *API) GetGSLBAPI() *GSLBAPI {
|
||||
return api.GSLB
|
||||
}
|
||||
|
||||
// GetIconAPI アイコンAPI取得
|
||||
func (api *API) GetIconAPI() *IconAPI {
|
||||
return api.Icon
|
||||
}
|
||||
|
||||
// GetInterfaceAPI インターフェースAPI取得
|
||||
func (api *API) GetInterfaceAPI() *InterfaceAPI {
|
||||
return api.Interface
|
||||
}
|
||||
|
||||
// GetInternetAPI ルーターAPI取得
|
||||
func (api *API) GetInternetAPI() *InternetAPI {
|
||||
return api.Internet
|
||||
}
|
||||
|
||||
// GetIPAddressAPI IPアドレスAPI取得
|
||||
func (api *API) GetIPAddressAPI() *IPAddressAPI {
|
||||
return api.IPAddress
|
||||
}
|
||||
|
||||
// GetIPv6AddrAPI IPv6アドレスAPI取得
|
||||
func (api *API) GetIPv6AddrAPI() *IPv6AddrAPI {
|
||||
return api.IPv6Addr
|
||||
}
|
||||
|
||||
// GetIPv6NetAPI IPv6ネットワークAPI取得
|
||||
func (api *API) GetIPv6NetAPI() *IPv6NetAPI {
|
||||
return api.IPv6Net
|
||||
}
|
||||
|
||||
// GetLicenseAPI ライセンスAPI取得
|
||||
func (api *API) GetLicenseAPI() *LicenseAPI {
|
||||
return api.License
|
||||
}
|
||||
|
||||
// GetLoadBalancerAPI ロードバランサーAPI取得
|
||||
func (api *API) GetLoadBalancerAPI() *LoadBalancerAPI {
|
||||
return api.LoadBalancer
|
||||
}
|
||||
|
||||
// GetMobileGatewayAPI モバイルゲートウェイAPI取得
|
||||
func (api *API) GetMobileGatewayAPI() *MobileGatewayAPI {
|
||||
return api.MobileGateway
|
||||
}
|
||||
|
||||
// GetNewsFeedAPI フィード(障害/メンテナンス情報)API取得
|
||||
func (api *API) GetNewsFeedAPI() *NewsFeedAPI {
|
||||
return api.NewsFeed
|
||||
}
|
||||
|
||||
// GetNFSAPI NFS API取得
|
||||
func (api *API) GetNFSAPI() *NFSAPI {
|
||||
return api.NFS
|
||||
}
|
||||
|
||||
// GetNoteAPI スタートアップAPI取得
|
||||
func (api *API) GetNoteAPI() *NoteAPI {
|
||||
return api.Note
|
||||
}
|
||||
|
||||
// GetPacketFilterAPI パケットフィルタAPI取得
|
||||
func (api *API) GetPacketFilterAPI() *PacketFilterAPI {
|
||||
return api.PacketFilter
|
||||
}
|
||||
|
||||
// GetPrivateHostAPI 専有ホストAPI取得
|
||||
func (api *API) GetPrivateHostAPI() *PrivateHostAPI {
|
||||
return api.PrivateHost
|
||||
}
|
||||
|
||||
// GetProductServerAPI サーバープランAPI取得
|
||||
func (api *API) GetProductServerAPI() *ProductServerAPI {
|
||||
return api.Product.GetProductServerAPI()
|
||||
}
|
||||
|
||||
// GetProductLicenseAPI ライセンスプランAPI取得
|
||||
func (api *API) GetProductLicenseAPI() *ProductLicenseAPI {
|
||||
return api.Product.GetProductLicenseAPI()
|
||||
}
|
||||
|
||||
// GetProductDiskAPI ディスクプランAPI取得
|
||||
func (api *API) GetProductDiskAPI() *ProductDiskAPI {
|
||||
return api.Product.GetProductDiskAPI()
|
||||
}
|
||||
|
||||
// GetProductInternetAPI ルータープランAPI取得
|
||||
func (api *API) GetProductInternetAPI() *ProductInternetAPI {
|
||||
return api.Product.GetProductInternetAPI()
|
||||
}
|
||||
|
||||
// GetPublicPriceAPI 価格情報API取得
|
||||
func (api *API) GetPublicPriceAPI() *PublicPriceAPI {
|
||||
return api.Product.GetPublicPriceAPI()
|
||||
}
|
||||
|
||||
// GetServerAPI サーバーAPI取得
|
||||
func (api *API) GetServerAPI() *ServerAPI {
|
||||
return api.Server
|
||||
}
|
||||
|
||||
// GetSIMAPI SIM API取得
|
||||
func (api *API) GetSIMAPI() *SIMAPI {
|
||||
return api.SIM
|
||||
}
|
||||
|
||||
// GetSimpleMonitorAPI シンプル監視API取得
|
||||
func (api *API) GetSimpleMonitorAPI() *SimpleMonitorAPI {
|
||||
return api.SimpleMonitor
|
||||
}
|
||||
|
||||
// GetSSHKeyAPI SSH公開鍵API取得
|
||||
func (api *API) GetSSHKeyAPI() *SSHKeyAPI {
|
||||
return api.SSHKey
|
||||
}
|
||||
|
||||
// GetSubnetAPI サブネットAPI取得
|
||||
func (api *API) GetSubnetAPI() *SubnetAPI {
|
||||
return api.Subnet
|
||||
}
|
||||
|
||||
// GetSwitchAPI スイッチAPI取得
|
||||
func (api *API) GetSwitchAPI() *SwitchAPI {
|
||||
return api.Switch
|
||||
}
|
||||
|
||||
// GetVPCRouterAPI VPCルーターAPI取得
|
||||
func (api *API) GetVPCRouterAPI() *VPCRouterAPI {
|
||||
return api.VPCRouter
|
||||
}
|
||||
|
||||
// GetWebAccelAPI ウェブアクセラレータAPI取得
|
||||
func (api *API) GetWebAccelAPI() *WebAccelAPI {
|
||||
return api.WebAccel
|
||||
}
|
||||
|
||||
// ProductAPI 製品情報関連API群
|
||||
type ProductAPI struct {
|
||||
Server *ProductServerAPI // サーバープランAPI
|
||||
License *ProductLicenseAPI // ライセンスプランAPI
|
||||
Disk *ProductDiskAPI // ディスクプランAPI
|
||||
Internet *ProductInternetAPI // ルータープランAPI
|
||||
PrivateHost *ProductPrivateHostAPI // 専有ホストプランAPI
|
||||
Price *PublicPriceAPI // 価格情報API
|
||||
}
|
||||
|
||||
// GetProductServerAPI サーバープランAPI取得
|
||||
func (api *ProductAPI) GetProductServerAPI() *ProductServerAPI {
|
||||
return api.Server
|
||||
}
|
||||
|
||||
// GetProductLicenseAPI ライセンスプランAPI取得
|
||||
func (api *ProductAPI) GetProductLicenseAPI() *ProductLicenseAPI {
|
||||
return api.License
|
||||
}
|
||||
|
||||
// GetProductDiskAPI ディスクプランAPI取得
|
||||
func (api *ProductAPI) GetProductDiskAPI() *ProductDiskAPI {
|
||||
return api.Disk
|
||||
}
|
||||
|
||||
// GetProductInternetAPI ルータープランAPI取得
|
||||
func (api *ProductAPI) GetProductInternetAPI() *ProductInternetAPI {
|
||||
return api.Internet
|
||||
}
|
||||
|
||||
// GetProductPrivateHostAPI 専有ホストプラン取得API
|
||||
func (api *ProductAPI) GetProductPrivateHostAPI() *ProductPrivateHostAPI {
|
||||
return api.PrivateHost
|
||||
}
|
||||
|
||||
// GetPublicPriceAPI 価格情報API取得
|
||||
func (api *ProductAPI) GetPublicPriceAPI() *PublicPriceAPI {
|
||||
return api.Price
|
||||
}
|
||||
|
||||
// FacilityAPI ファシリティ関連API群
|
||||
type FacilityAPI struct {
|
||||
Region *RegionAPI // リージョンAPI
|
||||
Zone *ZoneAPI // ゾーンAPI
|
||||
}
|
||||
|
||||
// GetRegionAPI リージョンAPI取得
|
||||
func (api *FacilityAPI) GetRegionAPI() *RegionAPI {
|
||||
return api.Region
|
||||
}
|
||||
|
||||
// GetZoneAPI ゾーンAPI取得
|
||||
func (api *FacilityAPI) GetZoneAPI() *ZoneAPI {
|
||||
return api.Zone
|
||||
}
|
||||
|
||||
func newAPI(client *Client) *API {
|
||||
return &API{
|
||||
AuthStatus: NewAuthStatusAPI(client),
|
||||
AutoBackup: NewAutoBackupAPI(client),
|
||||
Archive: NewArchiveAPI(client),
|
||||
Bill: NewBillAPI(client),
|
||||
Bridge: NewBridgeAPI(client),
|
||||
CDROM: NewCDROMAPI(client),
|
||||
Database: NewDatabaseAPI(client),
|
||||
Disk: NewDiskAPI(client),
|
||||
DNS: NewDNSAPI(client),
|
||||
Facility: &FacilityAPI{
|
||||
Region: NewRegionAPI(client),
|
||||
Zone: NewZoneAPI(client),
|
||||
},
|
||||
GSLB: NewGSLBAPI(client),
|
||||
Icon: NewIconAPI(client),
|
||||
Interface: NewInterfaceAPI(client),
|
||||
Internet: NewInternetAPI(client),
|
||||
IPAddress: NewIPAddressAPI(client),
|
||||
IPv6Addr: NewIPv6AddrAPI(client),
|
||||
IPv6Net: NewIPv6NetAPI(client),
|
||||
License: NewLicenseAPI(client),
|
||||
LoadBalancer: NewLoadBalancerAPI(client),
|
||||
MobileGateway: NewMobileGatewayAPI(client),
|
||||
NewsFeed: NewNewsFeedAPI(client),
|
||||
NFS: NewNFSAPI(client),
|
||||
Note: NewNoteAPI(client),
|
||||
PacketFilter: NewPacketFilterAPI(client),
|
||||
PrivateHost: NewPrivateHostAPI(client),
|
||||
Product: &ProductAPI{
|
||||
Server: NewProductServerAPI(client),
|
||||
License: NewProductLicenseAPI(client),
|
||||
Disk: NewProductDiskAPI(client),
|
||||
Internet: NewProductInternetAPI(client),
|
||||
PrivateHost: NewProductPrivateHostAPI(client),
|
||||
Price: NewPublicPriceAPI(client),
|
||||
},
|
||||
Server: NewServerAPI(client),
|
||||
SIM: NewSIMAPI(client),
|
||||
SimpleMonitor: NewSimpleMonitorAPI(client),
|
||||
SSHKey: NewSSHKeyAPI(client),
|
||||
Subnet: NewSubnetAPI(client),
|
||||
Switch: NewSwitchAPI(client),
|
||||
VPCRouter: NewVPCRouterAPI(client),
|
||||
WebAccel: NewWebAccelAPI(client),
|
||||
}
|
||||
}
|
429
vendor/github.com/sacloud/libsacloud/api/database.go
generated
vendored
Normal file
429
vendor/github.com/sacloud/libsacloud/api/database.go
generated
vendored
Normal file
@ -0,0 +1,429 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"time"
|
||||
)
|
||||
|
||||
//HACK: さくらのAPI側仕様: Applianceの内容によってJSONフォーマットが異なるため
|
||||
// ロードバランサ/VPCルータそれぞれでリクエスト/レスポンスデータ型を定義する。
|
||||
|
||||
// SearchDatabaseResponse データベース検索レスポンス
|
||||
type SearchDatabaseResponse struct {
|
||||
// Total 総件数
|
||||
Total int `json:",omitempty"`
|
||||
// From ページング開始位置
|
||||
From int `json:",omitempty"`
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// Databases データベースリスト
|
||||
Databases []sacloud.Database `json:"Appliances,omitempty"`
|
||||
}
|
||||
|
||||
type databaseRequest struct {
|
||||
Database *sacloud.Database `json:"Appliance,omitempty"`
|
||||
From int `json:",omitempty"`
|
||||
Count int `json:",omitempty"`
|
||||
Sort []string `json:",omitempty"`
|
||||
Filter map[string]interface{} `json:",omitempty"`
|
||||
Exclude []string `json:",omitempty"`
|
||||
Include []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type databaseResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
*sacloud.Database `json:"Appliance,omitempty"`
|
||||
// Success
|
||||
Success interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{}で受ける
|
||||
}
|
||||
|
||||
type databaseStatusResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
Success interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{}
|
||||
Appliance *struct {
|
||||
SettingsResponse *sacloud.DatabaseStatus
|
||||
}
|
||||
}
|
||||
|
||||
type databaseBackupResponse struct {
|
||||
Log string `json:",omitempty"`
|
||||
IsOk bool `json:"is_ok,omitempty"`
|
||||
}
|
||||
|
||||
// DatabaseAPI データベースAPI
|
||||
type DatabaseAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewDatabaseAPI データベースAPI作成
|
||||
func NewDatabaseAPI(client *Client) *DatabaseAPI {
|
||||
return &DatabaseAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "appliance"
|
||||
},
|
||||
FuncBaseSearchCondition: func() *sacloud.Request {
|
||||
res := &sacloud.Request{}
|
||||
res.AddFilter("Class", "database")
|
||||
return res
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Find 検索
|
||||
func (api *DatabaseAPI) Find() (*SearchDatabaseResponse, error) {
|
||||
data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res SearchDatabaseResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (api *DatabaseAPI) request(f func(*databaseResponse) error) (*sacloud.Database, error) {
|
||||
res := &databaseResponse{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Database, nil
|
||||
}
|
||||
|
||||
func (api *DatabaseAPI) createRequest(value *sacloud.Database) *databaseResponse {
|
||||
return &databaseResponse{Database: value}
|
||||
}
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *DatabaseAPI) New(values *sacloud.CreateDatabaseValue) *sacloud.Database {
|
||||
return sacloud.CreateNewDatabase(values)
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *DatabaseAPI) Create(value *sacloud.Database) (*sacloud.Database, error) {
|
||||
return api.request(func(res *databaseResponse) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *DatabaseAPI) Read(id int64) (*sacloud.Database, error) {
|
||||
return api.request(func(res *databaseResponse) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Status DBの設定/起動状態の取得
|
||||
func (api *DatabaseAPI) Status(id int64) (*sacloud.DatabaseStatus, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/status", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
res := &databaseStatusResponse{}
|
||||
err := api.baseAPI.request(method, uri, nil, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Appliance.SettingsResponse, nil
|
||||
}
|
||||
|
||||
// Backup バックアップ取得
|
||||
func (api *DatabaseAPI) Backup(id int64) (string, error) {
|
||||
var (
|
||||
method = "POST"
|
||||
uri = fmt.Sprintf("%s/%d/action/history", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
body := map[string]interface{}{
|
||||
"Appliance": map[string]interface{}{
|
||||
"Settings": map[string]interface{}{
|
||||
"DBConf": map[string]interface{}{
|
||||
"backup": map[string]string{
|
||||
"availability": "discontinued",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
res := &databaseBackupResponse{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return res.Log, nil
|
||||
}
|
||||
|
||||
// DownloadLog ログ取得
|
||||
func (api *DatabaseAPI) DownloadLog(id int64, logID string) (string, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/download/log/%s", api.getResourceURL(), id, logID)
|
||||
)
|
||||
|
||||
res := &databaseBackupResponse{}
|
||||
err := api.baseAPI.request(method, uri, nil, res)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return res.Log, nil
|
||||
}
|
||||
|
||||
// Restore バックアップからの復元
|
||||
func (api *DatabaseAPI) Restore(id int64, backupID string) (string, error) {
|
||||
var (
|
||||
method = "POST"
|
||||
uri = fmt.Sprintf("%s/%d/action/history/%s", api.getResourceURL(), id, backupID)
|
||||
)
|
||||
|
||||
body := map[string]interface{}{
|
||||
"Appliance": map[string]interface{}{},
|
||||
}
|
||||
|
||||
res := &databaseBackupResponse{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return res.Log, nil
|
||||
}
|
||||
|
||||
// DeleteBackup バックアップの削除
|
||||
func (api *DatabaseAPI) DeleteBackup(id int64, backupID string) (string, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/action/history/%s", api.getResourceURL(), id, backupID)
|
||||
)
|
||||
|
||||
body := map[string]interface{}{
|
||||
"Appliance": map[string]interface{}{},
|
||||
}
|
||||
|
||||
res := &databaseBackupResponse{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return res.Log, nil
|
||||
}
|
||||
|
||||
// HistoryLock バックアップ削除ロック
|
||||
func (api *DatabaseAPI) HistoryLock(id int64, backupID string) (string, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/action/history-lock/%s", api.getResourceURL(), id, backupID)
|
||||
)
|
||||
|
||||
body := map[string]interface{}{
|
||||
"Appliance": map[string]interface{}{},
|
||||
}
|
||||
|
||||
res := &databaseBackupResponse{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return res.Log, nil
|
||||
}
|
||||
|
||||
// HistoryUnlock バックアップ削除アンロック
|
||||
func (api *DatabaseAPI) HistoryUnlock(id int64, backupID string) (string, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/action/history-lock/%s", api.getResourceURL(), id, backupID)
|
||||
)
|
||||
|
||||
body := map[string]interface{}{
|
||||
"Appliance": map[string]interface{}{},
|
||||
}
|
||||
|
||||
res := &databaseBackupResponse{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return res.Log, nil
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *DatabaseAPI) Update(id int64, value *sacloud.Database) (*sacloud.Database, error) {
|
||||
return api.request(func(res *databaseResponse) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateSetting 設定更新
|
||||
func (api *DatabaseAPI) UpdateSetting(id int64, value *sacloud.Database) (*sacloud.Database, error) {
|
||||
req := &sacloud.Database{
|
||||
// Settings
|
||||
Settings: value.Settings,
|
||||
}
|
||||
return api.request(func(res *databaseResponse) error {
|
||||
return api.update(id, api.createRequest(req), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *DatabaseAPI) Delete(id int64) (*sacloud.Database, error) {
|
||||
return api.request(func(res *databaseResponse) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Config 設定変更の反映
|
||||
func (api *DatabaseAPI) Config(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/config", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// IsUp 起動しているか判定
|
||||
func (api *DatabaseAPI) IsUp(id int64) (bool, error) {
|
||||
lb, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return lb.Instance.IsUp(), nil
|
||||
}
|
||||
|
||||
// IsDown ダウンしているか判定
|
||||
func (api *DatabaseAPI) IsDown(id int64) (bool, error) {
|
||||
lb, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return lb.Instance.IsDown(), nil
|
||||
}
|
||||
|
||||
// IsDatabaseRunning データベースプロセスが起動しているか判定
|
||||
func (api *DatabaseAPI) IsDatabaseRunning(id int64) (bool, error) {
|
||||
db, err := api.Status(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return db.IsUp(), nil
|
||||
|
||||
}
|
||||
|
||||
// Boot 起動
|
||||
func (api *DatabaseAPI) Boot(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Shutdown シャットダウン(graceful)
|
||||
func (api *DatabaseAPI) Shutdown(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Stop シャットダウン(force)
|
||||
func (api *DatabaseAPI) Stop(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]bool{"Force": true})
|
||||
}
|
||||
|
||||
// RebootForce 再起動
|
||||
func (api *DatabaseAPI) RebootForce(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/reset", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// ResetForce リセット
|
||||
func (api *DatabaseAPI) ResetForce(id int64, recycleProcess bool) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/reset", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]bool{"RecycleProcess": recycleProcess})
|
||||
}
|
||||
|
||||
// SleepUntilUp 起動するまで待機
|
||||
func (api *DatabaseAPI) SleepUntilUp(id int64, timeout time.Duration) error {
|
||||
handler := waitingForUpFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// SleepUntilDatabaseRunning 起動するまで待機
|
||||
func (api *DatabaseAPI) SleepUntilDatabaseRunning(id int64, timeout time.Duration, maxRetry int) error {
|
||||
handler := waitingForUpFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, maxRetry)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// SleepUntilDown ダウンするまで待機
|
||||
func (api *DatabaseAPI) SleepUntilDown(id int64, timeout time.Duration) error {
|
||||
handler := waitingForDownFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// SleepWhileCopying コピー終了まで待機
|
||||
func (api *DatabaseAPI) SleepWhileCopying(id int64, timeout time.Duration, maxRetry int) error {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, maxRetry)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// AsyncSleepWhileCopying コピー終了まで待機(非同期)
|
||||
func (api *DatabaseAPI) AsyncSleepWhileCopying(id int64, timeout time.Duration, maxRetry int) (chan (interface{}), chan (interface{}), chan (error)) {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, maxRetry)
|
||||
return poll(handler, timeout)
|
||||
}
|
||||
|
||||
// MonitorCPU CPUアクティビティーモニター取得
|
||||
func (api *DatabaseAPI) MonitorCPU(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.applianceMonitorBy(id, "cpu", 0, body)
|
||||
}
|
||||
|
||||
// MonitorDatabase データーベース固有項目アクティビティモニター取得
|
||||
func (api *DatabaseAPI) MonitorDatabase(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.applianceMonitorBy(id, "database", 0, body)
|
||||
}
|
||||
|
||||
// MonitorInterface NICアクティビティーモニター取得
|
||||
func (api *DatabaseAPI) MonitorInterface(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.applianceMonitorBy(id, "interface", 0, body)
|
||||
}
|
||||
|
||||
// MonitorSystemDisk システムディスクアクティビティーモニター取得
|
||||
func (api *DatabaseAPI) MonitorSystemDisk(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.applianceMonitorBy(id, "disk", 1, body)
|
||||
}
|
||||
|
||||
// MonitorBackupDisk バックアップディスクアクティビティーモニター取得
|
||||
func (api *DatabaseAPI) MonitorBackupDisk(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.applianceMonitorBy(id, "disk", 2, body)
|
||||
}
|
238
vendor/github.com/sacloud/libsacloud/api/database_gen.go
generated
vendored
Normal file
238
vendor/github.com/sacloud/libsacloud/api/database_gen.go
generated
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [DatabaseAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *DatabaseAPI) Reset() *DatabaseAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *DatabaseAPI) Offset(offset int) *DatabaseAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *DatabaseAPI) Limit(limit int) *DatabaseAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *DatabaseAPI) Include(key string) *DatabaseAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *DatabaseAPI) Exclude(key string) *DatabaseAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定項目でのフィルター
|
||||
func (api *DatabaseAPI) FilterBy(key string, value interface{}) *DatabaseAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *DatabaseAPI) FilterMultiBy(key string, value interface{}) *DatabaseAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *DatabaseAPI) WithNameLike(name string) *DatabaseAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *DatabaseAPI) WithTag(tag string) *DatabaseAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *DatabaseAPI) WithTags(tags []string) *DatabaseAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *DatabaseAPI) WithSizeGib(size int) *DatabaseAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *DatabaseAPI) WithSharedScope() *DatabaseAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *DatabaseAPI) WithUserScope() *DatabaseAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *DatabaseAPI) SortBy(key string, reverse bool) *DatabaseAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *DatabaseAPI) SortByName(reverse bool) *DatabaseAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *DatabaseAPI) SortBySize(reverse bool) *DatabaseAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *DatabaseAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *DatabaseAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *DatabaseAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *DatabaseAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *DatabaseAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定項目でのフィルター
|
||||
func (api *DatabaseAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *DatabaseAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *DatabaseAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *DatabaseAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *DatabaseAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *DatabaseAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *DatabaseAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *DatabaseAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *DatabaseAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *DatabaseAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *DatabaseAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *DatabaseAPI) New() *sacloud.Database {
|
||||
// return &sacloud.Database{}
|
||||
// }
|
||||
|
||||
// func (api *DatabaseAPI) Create(value *sacloud.Database) (*sacloud.Database, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *DatabaseAPI) Read(id string) (*sacloud.Database, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *DatabaseAPI) Update(id string, value *sacloud.Database) (*sacloud.Database, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *DatabaseAPI) Delete(id string) (*sacloud.Database, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *DatabaseAPI) setStateValue(setFunc func(*sacloud.Request)) *DatabaseAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *DatabaseAPI) request(f func(*sacloud.Response) error) (*sacloud.Database, error) {
|
||||
// res := &sacloud.Response{}
|
||||
// err := f(res)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return res.Database, nil
|
||||
//}
|
||||
//
|
||||
//func (api *DatabaseAPI) createRequest(value *sacloud.Database) *sacloud.Request {
|
||||
// req := &sacloud.Request{}
|
||||
// req.Database = value
|
||||
// return req
|
||||
//}
|
283
vendor/github.com/sacloud/libsacloud/api/disk.go
generated
vendored
Normal file
283
vendor/github.com/sacloud/libsacloud/api/disk.go
generated
vendored
Normal file
@ -0,0 +1,283 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// allowDiskEditTags ディスクの編集可否判定に用いるタグ
|
||||
allowDiskEditTags = []string{
|
||||
"os-unix",
|
||||
"os-linux",
|
||||
}
|
||||
|
||||
// bundleInfoWindowsHostClass ディスクの編集可否判定に用いる、BundleInfoでのWindows判定文字列
|
||||
bundleInfoWindowsHostClass = "ms_windows"
|
||||
)
|
||||
|
||||
// DiskAPI ディスクAPI
|
||||
type DiskAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewDiskAPI ディスクAPI作成
|
||||
func NewDiskAPI(client *Client) *DiskAPI {
|
||||
return &DiskAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
// FuncGetResourceURL
|
||||
FuncGetResourceURL: func() string {
|
||||
return "disk"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// SortByConnectionOrder 接続順でのソート
|
||||
func (api *DiskAPI) SortByConnectionOrder(reverse bool) *DiskAPI {
|
||||
api.sortBy("ConnectionOrder", reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithServerID サーバーID条件
|
||||
func (api *DiskAPI) WithServerID(id int64) *DiskAPI {
|
||||
api.FilterBy("Server.ID", id)
|
||||
return api
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *DiskAPI) Create(value *sacloud.Disk) (*sacloud.Disk, error) {
|
||||
//HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないため文字列で受ける
|
||||
type diskResponse struct {
|
||||
*sacloud.Response
|
||||
// Success
|
||||
Success string `json:",omitempty"`
|
||||
}
|
||||
res := &diskResponse{}
|
||||
err := api.create(api.createRequest(value), res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Disk, nil
|
||||
}
|
||||
|
||||
// NewCondig ディスクの修正用パラメーター作成
|
||||
func (api *DiskAPI) NewCondig() *sacloud.DiskEditValue {
|
||||
return &sacloud.DiskEditValue{}
|
||||
}
|
||||
|
||||
// Config ディスクの修正
|
||||
func (api *DiskAPI) Config(id int64, disk *sacloud.DiskEditValue) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/config", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, disk)
|
||||
}
|
||||
|
||||
func (api *DiskAPI) install(id int64, body *sacloud.Disk) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/install", api.getResourceURL(), id)
|
||||
)
|
||||
//HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないため文字列で受ける
|
||||
type diskResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
// Success
|
||||
Success string `json:",omitempty"`
|
||||
}
|
||||
res := &diskResponse{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return res.IsOk, nil
|
||||
}
|
||||
|
||||
// ReinstallFromBlank ブランクディスクから再インストール
|
||||
func (api *DiskAPI) ReinstallFromBlank(id int64, sizeMB int) (bool, error) {
|
||||
var body = &sacloud.Disk{}
|
||||
body.SetSizeMB(sizeMB)
|
||||
|
||||
return api.install(id, body)
|
||||
}
|
||||
|
||||
// ReinstallFromArchive アーカイブからの再インストール
|
||||
func (api *DiskAPI) ReinstallFromArchive(id int64, archiveID int64, distantFrom ...int64) (bool, error) {
|
||||
var body = &sacloud.Disk{}
|
||||
body.SetSourceArchive(archiveID)
|
||||
if len(distantFrom) > 0 {
|
||||
body.SetDistantFrom(distantFrom)
|
||||
}
|
||||
return api.install(id, body)
|
||||
}
|
||||
|
||||
// ReinstallFromDisk ディスクからの再インストール
|
||||
func (api *DiskAPI) ReinstallFromDisk(id int64, diskID int64, distantFrom ...int64) (bool, error) {
|
||||
var body = &sacloud.Disk{}
|
||||
body.SetSourceDisk(diskID)
|
||||
if len(distantFrom) > 0 {
|
||||
body.SetDistantFrom(distantFrom)
|
||||
}
|
||||
return api.install(id, body)
|
||||
}
|
||||
|
||||
// ToBlank ディスクを空にする
|
||||
func (api *DiskAPI) ToBlank(diskID int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/to/blank", api.getResourceURL(), diskID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// ResizePartition パーティションのリサイズ
|
||||
func (api *DiskAPI) ResizePartition(diskID int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/resize-partition", api.getResourceURL(), diskID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// DisconnectFromServer サーバーとの接続解除
|
||||
func (api *DiskAPI) DisconnectFromServer(diskID int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/to/server", api.getResourceURL(), diskID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// ConnectToServer サーバーとの接続
|
||||
func (api *DiskAPI) ConnectToServer(diskID int64, serverID int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/to/server/%d", api.getResourceURL(), diskID, serverID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// State ディスクの状態を取得し有効な状態か判定
|
||||
func (api *DiskAPI) State(diskID int64) (bool, error) {
|
||||
disk, err := api.Read(diskID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return disk.IsAvailable(), nil
|
||||
}
|
||||
|
||||
// SleepWhileCopying コピー終了まで待機
|
||||
func (api *DiskAPI) SleepWhileCopying(id int64, timeout time.Duration) error {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// AsyncSleepWhileCopying コピー終了まで待機(非同期)
|
||||
func (api *DiskAPI) AsyncSleepWhileCopying(id int64, timeout time.Duration) (chan (interface{}), chan (interface{}), chan (error)) {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return poll(handler, timeout)
|
||||
}
|
||||
|
||||
// Monitor アクティビティーモニター取得
|
||||
func (api *DiskAPI) Monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.monitor(id, body)
|
||||
}
|
||||
|
||||
// CanEditDisk ディスクの修正が可能か判定
|
||||
func (api *DiskAPI) CanEditDisk(id int64) (bool, error) {
|
||||
|
||||
disk, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if disk == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// BundleInfoがあれば編集不可
|
||||
if disk.BundleInfo != nil && disk.BundleInfo.HostClass == bundleInfoWindowsHostClass {
|
||||
// Windows
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// SophosUTMであれば編集不可
|
||||
if disk.HasTag("pkg-sophosutm") || disk.IsSophosUTM() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// ソースアーカイブ/ソースディスクともに持っていない場合
|
||||
if disk.SourceArchive == nil && disk.SourceDisk == nil {
|
||||
//ブランクディスクがソース
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for _, t := range allowDiskEditTags {
|
||||
if disk.HasTag(t) {
|
||||
// 対応OSインストール済みディスク
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ここまできても判定できないならソースに投げる
|
||||
if disk.SourceDisk != nil && disk.SourceDisk.Availability != "discontinued" {
|
||||
return api.client.Disk.CanEditDisk(disk.SourceDisk.ID)
|
||||
}
|
||||
if disk.SourceArchive != nil && disk.SourceArchive.Availability != "discontinued" {
|
||||
return api.client.Archive.CanEditDisk(disk.SourceArchive.ID)
|
||||
}
|
||||
|
||||
return false, nil
|
||||
|
||||
}
|
||||
|
||||
// GetPublicArchiveIDFromAncestors 祖先の中からパブリックアーカイブのIDを検索
|
||||
func (api *DiskAPI) GetPublicArchiveIDFromAncestors(id int64) (int64, bool) {
|
||||
|
||||
emptyID := int64(0)
|
||||
|
||||
disk, err := api.Read(id)
|
||||
if err != nil {
|
||||
return emptyID, false
|
||||
}
|
||||
|
||||
if disk == nil {
|
||||
return emptyID, false
|
||||
}
|
||||
|
||||
// BundleInfoがあれば編集不可
|
||||
if disk.BundleInfo != nil && disk.BundleInfo.HostClass == bundleInfoWindowsHostClass {
|
||||
// Windows
|
||||
return emptyID, false
|
||||
}
|
||||
|
||||
// SophosUTMであれば編集不可
|
||||
if disk.HasTag("pkg-sophosutm") || disk.IsSophosUTM() {
|
||||
return emptyID, false
|
||||
}
|
||||
|
||||
for _, t := range allowDiskEditTags {
|
||||
if disk.HasTag(t) {
|
||||
// 対応OSインストール済みディスク
|
||||
return disk.ID, true
|
||||
}
|
||||
}
|
||||
|
||||
// ここまできても判定できないならソースに投げる
|
||||
if disk.SourceDisk != nil && disk.SourceDisk.Availability != "discontinued" {
|
||||
return api.client.Disk.GetPublicArchiveIDFromAncestors(disk.SourceDisk.ID)
|
||||
}
|
||||
if disk.SourceArchive != nil && disk.SourceArchive.Availability != "discontinued" {
|
||||
return api.client.Archive.GetPublicArchiveIDFromAncestors(disk.SourceArchive.ID)
|
||||
}
|
||||
return emptyID, false
|
||||
|
||||
}
|
228
vendor/github.com/sacloud/libsacloud/api/disk_gen.go
generated
vendored
Normal file
228
vendor/github.com/sacloud/libsacloud/api/disk_gen.go
generated
vendored
Normal file
@ -0,0 +1,228 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [DiskAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *DiskAPI) Reset() *DiskAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *DiskAPI) Offset(offset int) *DiskAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *DiskAPI) Limit(limit int) *DiskAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *DiskAPI) Include(key string) *DiskAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *DiskAPI) Exclude(key string) *DiskAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *DiskAPI) FilterBy(key string, value interface{}) *DiskAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *DiskAPI) FilterMultiBy(key string, value interface{}) *DiskAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *DiskAPI) WithNameLike(name string) *DiskAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *DiskAPI) WithTag(tag string) *DiskAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *DiskAPI) WithTags(tags []string) *DiskAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// WithSizeGib サイズ条件
|
||||
func (api *DiskAPI) WithSizeGib(size int) *DiskAPI {
|
||||
api.FilterBy("SizeMB", size*1024)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *DiskAPI) SortBy(key string, reverse bool) *DiskAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *DiskAPI) SortByName(reverse bool) *DiskAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortBySize サイズでのソート
|
||||
func (api *DiskAPI) SortBySize(reverse bool) *DiskAPI {
|
||||
api.sortBy("SizeMB", reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *DiskAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *DiskAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *DiskAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *DiskAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *DiskAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *DiskAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *DiskAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *DiskAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *DiskAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *DiskAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// SetSizeGib サイズ条件
|
||||
func (api *DiskAPI) SetSizeGib(size int) {
|
||||
api.FilterBy("SizeMB", size*1024)
|
||||
}
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *DiskAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *DiskAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// SetSortBySize サイズでのソート
|
||||
func (api *DiskAPI) SetSortBySize(reverse bool) {
|
||||
api.sortBy("SizeMB", reverse)
|
||||
}
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *DiskAPI) New() *sacloud.Disk {
|
||||
return sacloud.CreateNewDisk()
|
||||
}
|
||||
|
||||
//func (api *DiskAPI) Create(value *sacloud.Disk) (*sacloud.Disk, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
//}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *DiskAPI) Read(id int64) (*sacloud.Disk, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *DiskAPI) Update(id int64, value *sacloud.Disk) (*sacloud.Disk, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *DiskAPI) Delete(id int64) (*sacloud.Disk, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *DiskAPI) setStateValue(setFunc func(*sacloud.Request)) *DiskAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *DiskAPI) request(f func(*sacloud.Response) error) (*sacloud.Disk, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Disk, nil
|
||||
}
|
||||
|
||||
func (api *DiskAPI) createRequest(value *sacloud.Disk) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.Disk = value
|
||||
return req
|
||||
}
|
206
vendor/github.com/sacloud/libsacloud/api/dns.go
generated
vendored
Normal file
206
vendor/github.com/sacloud/libsacloud/api/dns.go
generated
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//HACK: さくらのAPI側仕様: CommonServiceItemsの内容によってJSONフォーマットが異なるため
|
||||
// DNS/GSLB/シンプル監視それぞれでリクエスト/レスポンスデータ型を定義する。
|
||||
|
||||
// SearchDNSResponse DNS検索レスポンス
|
||||
type SearchDNSResponse struct {
|
||||
// Total 総件数
|
||||
Total int `json:",omitempty"`
|
||||
// From ページング開始位置
|
||||
From int `json:",omitempty"`
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// CommonServiceDNSItems DNSリスト
|
||||
CommonServiceDNSItems []sacloud.DNS `json:"CommonServiceItems,omitempty"`
|
||||
}
|
||||
type dnsRequest struct {
|
||||
CommonServiceDNSItem *sacloud.DNS `json:"CommonServiceItem,omitempty"`
|
||||
From int `json:",omitempty"`
|
||||
Count int `json:",omitempty"`
|
||||
Sort []string `json:",omitempty"`
|
||||
Filter map[string]interface{} `json:",omitempty"`
|
||||
Exclude []string `json:",omitempty"`
|
||||
Include []string `json:",omitempty"`
|
||||
}
|
||||
type dnsResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
*sacloud.DNS `json:"CommonServiceItem,omitempty"`
|
||||
}
|
||||
|
||||
// DNSAPI DNS API
|
||||
type DNSAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewDNSAPI DNS API作成
|
||||
func NewDNSAPI(client *Client) *DNSAPI {
|
||||
return &DNSAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "commonserviceitem"
|
||||
},
|
||||
FuncBaseSearchCondition: func() *sacloud.Request {
|
||||
res := &sacloud.Request{}
|
||||
res.AddFilter("Provider.Class", "dns")
|
||||
return res
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Find 検索
|
||||
func (api *DNSAPI) Find() (*SearchDNSResponse, error) {
|
||||
|
||||
data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res SearchDNSResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (api *DNSAPI) request(f func(*dnsResponse) error) (*sacloud.DNS, error) {
|
||||
res := &dnsResponse{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.DNS, nil
|
||||
}
|
||||
|
||||
func (api *DNSAPI) createRequest(value *sacloud.DNS) *dnsRequest {
|
||||
req := &dnsRequest{}
|
||||
req.CommonServiceDNSItem = value
|
||||
return req
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *DNSAPI) Create(value *sacloud.DNS) (*sacloud.DNS, error) {
|
||||
return api.request(func(res *dnsResponse) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *DNSAPI) New(zoneName string) *sacloud.DNS {
|
||||
return sacloud.CreateNewDNS(zoneName)
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *DNSAPI) Read(id int64) (*sacloud.DNS, error) {
|
||||
return api.request(func(res *dnsResponse) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *DNSAPI) Update(id int64, value *sacloud.DNS) (*sacloud.DNS, error) {
|
||||
return api.request(func(res *dnsResponse) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *DNSAPI) Delete(id int64) (*sacloud.DNS, error) {
|
||||
return api.request(func(res *dnsResponse) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// SetupDNSRecord DNSレコード作成
|
||||
func (api *DNSAPI) SetupDNSRecord(zoneName string, hostName string, ip string) ([]string, error) {
|
||||
|
||||
dnsItem, err := api.findOrCreateBy(zoneName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if strings.HasSuffix(hostName, zoneName) {
|
||||
hostName = strings.Replace(hostName, zoneName, "", -1)
|
||||
}
|
||||
|
||||
dnsItem.Settings.DNS.AddDNSRecordSet(hostName, ip)
|
||||
|
||||
res, err := api.updateDNSRecord(dnsItem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if dnsItem.ID == sacloud.EmptyID {
|
||||
return res.Status.NS, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
}
|
||||
|
||||
// DeleteDNSRecord DNSレコード削除
|
||||
func (api *DNSAPI) DeleteDNSRecord(zoneName string, hostName string, ip string) error {
|
||||
dnsItem, err := api.findOrCreateBy(zoneName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dnsItem.Settings.DNS.DeleteDNSRecordSet(hostName, ip)
|
||||
|
||||
if dnsItem.HasDNSRecord() {
|
||||
_, err = api.updateDNSRecord(dnsItem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
_, err = api.Delete(dnsItem.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (api *DNSAPI) findOrCreateBy(zoneName string) (*sacloud.DNS, error) {
|
||||
|
||||
res, err := api.Reset().WithNameLike(zoneName).Limit(1).Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//すでに登録されている場合
|
||||
var dnsItem *sacloud.DNS
|
||||
if res.Count > 0 {
|
||||
dnsItem = &res.CommonServiceDNSItems[0]
|
||||
} else {
|
||||
dnsItem = sacloud.CreateNewDNS(zoneName)
|
||||
}
|
||||
|
||||
return dnsItem, nil
|
||||
}
|
||||
|
||||
func (api *DNSAPI) updateDNSRecord(dnsItem *sacloud.DNS) (*sacloud.DNS, error) {
|
||||
|
||||
var item *sacloud.DNS
|
||||
var err error
|
||||
|
||||
if dnsItem.ID == sacloud.EmptyID {
|
||||
item, err = api.Create(dnsItem)
|
||||
} else {
|
||||
item, err = api.Update(dnsItem.ID, dnsItem)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return item, nil
|
||||
}
|
238
vendor/github.com/sacloud/libsacloud/api/dns_gen.go
generated
vendored
Normal file
238
vendor/github.com/sacloud/libsacloud/api/dns_gen.go
generated
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [DNSAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *DNSAPI) Reset() *DNSAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *DNSAPI) Offset(offset int) *DNSAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *DNSAPI) Limit(limit int) *DNSAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *DNSAPI) Include(key string) *DNSAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *DNSAPI) Exclude(key string) *DNSAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *DNSAPI) FilterBy(key string, value interface{}) *DNSAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *DNSAPI) FilterMultiBy(key string, value interface{}) *DNSAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *DNSAPI) WithNameLike(name string) *DNSAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *DNSAPI) WithTag(tag string) *DNSAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *DNSAPI) WithTags(tags []string) *DNSAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *DNSAPI) WithSizeGib(size int) *DNSAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *DNSAPI) WithSharedScope() *DNSAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *DNSAPI) WithUserScope() *DNSAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *DNSAPI) SortBy(key string, reverse bool) *DNSAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *DNSAPI) SortByName(reverse bool) *DNSAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *DNSAPI) SortBySize(reverse bool) *DNSAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *DNSAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *DNSAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *DNSAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *DNSAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *DNSAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *DNSAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *DNSAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *DNSAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *DNSAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *DNSAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *DNSAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *DNSAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *DNSAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *DNSAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *DNSAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *DNSAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *DNSAPI) New() *sacloud.DNS {
|
||||
// return &sacloud.DNS{}
|
||||
// }
|
||||
|
||||
// func (api *DNSAPI) Create(value *sacloud.DNS) (*sacloud.DNS, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *DNSAPI) Read(id string) (*sacloud.DNS, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *DNSAPI) Update(id string, value *sacloud.DNS) (*sacloud.DNS, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *DNSAPI) Delete(id string) (*sacloud.DNS, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *DNSAPI) setStateValue(setFunc func(*sacloud.Request)) *DNSAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *DNSAPI) request(f func(*sacloud.Response) error) (*sacloud.DNS, error) {
|
||||
// res := &sacloud.Response{}
|
||||
// err := f(res)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return res.DNS, nil
|
||||
//}
|
||||
//
|
||||
//func (api *DNSAPI) createRequest(value *sacloud.DNS) *dnsRequest {
|
||||
// req := &dnsRequest{}
|
||||
// req.CommonServiceDNSItem = value
|
||||
// return req
|
||||
//}
|
176
vendor/github.com/sacloud/libsacloud/api/doc.go
generated
vendored
Normal file
176
vendor/github.com/sacloud/libsacloud/api/doc.go
generated
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
// Package api is the Low Level APIs for maganing resources on SakuraCloud.
|
||||
//
|
||||
// さくらのクラウドでのリソース操作用の低レベルAPIです。
|
||||
// さくらのクラウドAPI呼び出しを行います。
|
||||
//
|
||||
// Basic usage
|
||||
//
|
||||
// はじめにAPIクライアントを作成します。以降は作成したAPIクライアントを通じて各操作を行います。
|
||||
//
|
||||
// APIクライアントの作成にはAPIトークン、APIシークレット、対象ゾーン情報が必要です。
|
||||
//
|
||||
// あらかじめ、さくらのクラウド コントロールパネルにてAPIキーを発行しておいてください。
|
||||
//
|
||||
// token := "PUT YOUR TOKEN"
|
||||
// secret := "PUT YOUR SECRET"
|
||||
// zone := "tk1a"
|
||||
//
|
||||
// // クライアントの作成
|
||||
// client := api.NewClient(token, secret, zone)
|
||||
//
|
||||
// Select target resource
|
||||
//
|
||||
// 操作対象のリソースごとにAPIクライアントのフィールドを用意しています。
|
||||
// 例えばサーバーの操作を行う場合はAPIクライアントの"Server"フィールドを通じて操作します。
|
||||
//
|
||||
// フィールドの一覧は[type API]のドキュメントを参照してください。
|
||||
//
|
||||
// // サーバーの検索の場合
|
||||
// client.Server.Find()
|
||||
//
|
||||
// // ディスクの検索の場合
|
||||
// client.Disk.Find()
|
||||
//
|
||||
//
|
||||
// Find resource
|
||||
//
|
||||
// リソースの検索を行うには、条件を指定してFind()を呼び出します。
|
||||
//
|
||||
// APIクライアントでは、検索条件の指定にFluent APIを採用しているため、メソッドチェーンで条件を指定できます。
|
||||
//
|
||||
// // サーバーの検索
|
||||
// res, err := client.Server.
|
||||
// WithNameLike("server name"). // サーバー名に"server name"が含まれる
|
||||
// Offset(0). // 検索結果の位置0(先頭)から取得
|
||||
// Limit(5). // 5件取得
|
||||
// Include("Name"). // 結果にName列を含める
|
||||
// Include("Description"). // 結果にDescription列を含める
|
||||
// Find() // 検索実施
|
||||
//
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// fmt.Printf("response: %#v", res.Servers)
|
||||
//
|
||||
// Create resource
|
||||
//
|
||||
// 新規作成用パラメーターを作成し、値を設定します。
|
||||
// その後APIクライアントのCreate()を呼び出します。
|
||||
//
|
||||
// // スイッチの作成
|
||||
// param := client.Switch.New() // 新規作成用パラメーターの作成
|
||||
// param.Name = "example" // 値の設定(名前)
|
||||
// param.Description = "example" // 値の設定(説明)
|
||||
// sw, err := client.Switch.Create(param) // 作成
|
||||
//
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// fmt.Printf("Created switch: %#v", sw)
|
||||
//
|
||||
// リソースの作成は非同期で行われます。
|
||||
//
|
||||
// このため、サーバーやディスクなどの作成に時間がかかるリソースに対して
|
||||
// Create()呼び出し直後に操作を行おうとした場合にエラーとなることがあります。
|
||||
//
|
||||
// 必要に応じて適切なメソッドを呼び出し、リソースが適切な状態になるまで待機してください。
|
||||
//
|
||||
// // パブリックアーカイブからディスク作成
|
||||
// archive, _ := client.Archive.FindLatestStableCentOS()
|
||||
// // ディスクの作成
|
||||
// param := client.Disk.New()
|
||||
// param.Name = "example" // 値の設定(名前)
|
||||
// param.SetSourceArchive(archive.ID) // コピー元にCentOSパブリックアーカイブを指定
|
||||
// disk, err := client.Disk.Create(param) // 作成
|
||||
//
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// // 作成完了まで待機
|
||||
// err = client.Disk.SleepWhileCopying(disk.ID, client.DefaultTimeoutDuration)
|
||||
//
|
||||
// // タイムアウト発生の場合errが返る
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// fmt.Printf("Created disk: %#v", disk)
|
||||
//
|
||||
// Update resource
|
||||
//
|
||||
// APIクライアントのUpdate()メソッドを呼び出します。
|
||||
//
|
||||
// req, err := client.Server.Find()
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// server := &req.Servers[0]
|
||||
//
|
||||
// // 更新
|
||||
// server.Name = "update" // サーバー名を変更
|
||||
// server.AppendTag("example-tag") // タグを追加
|
||||
// updatedServer, err := client.Server.Update(server.ID, server) //更新実行
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// fmt.Printf("Updated server: %#v", updatedServer)
|
||||
//
|
||||
// 更新内容によってはあらかじめシャットダウンなどのリソースの操作が必要になる場合があります。
|
||||
//
|
||||
// 詳細はさくらのクラウド ドキュメントを参照下さい。
|
||||
// http://cloud.sakura.ad.jp/document/
|
||||
//
|
||||
// Delete resource
|
||||
//
|
||||
// APIクライアントのDeleteメソッドを呼び出します。
|
||||
//
|
||||
// // 削除
|
||||
// deletedSwitch, err := client.Switch.Delete(sw.ID)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// fmt.Printf("Deleted switch: %#v", deletedSwitch)
|
||||
//
|
||||
// 対象リソースによってはあらかじめシャットダウンや切断などの操作が必要になる場合があります。
|
||||
//
|
||||
// 詳細はさくらのクラウド ドキュメントを参照下さい。
|
||||
// http://cloud.sakura.ad.jp/document/
|
||||
//
|
||||
// PowerManagement
|
||||
//
|
||||
// サーバーやアプライアンスなどの電源操作もAPIを通じて行えます。
|
||||
//
|
||||
// // 起動
|
||||
// _, err = client.Server.Boot(server.ID)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// // 起動完了まで待機
|
||||
// err = client.Server.SleepUntilUp(server.ID, client.DefaultTimeoutDuration)
|
||||
//
|
||||
// // シャットダウン
|
||||
// _, err = client.Server.Shutdown(server.ID) // gracefulシャットダウン
|
||||
//
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// // ダウンまで待機
|
||||
// err = client.Server.SleepUntilDown(server.ID, client.DefaultTimeoutDuration)
|
||||
//
|
||||
// 電源関連のAPI呼び出しは非同期で行われます。
|
||||
//
|
||||
// 必要に応じて適切なメソッドを呼び出し、リソースが適切な状態になるまで待機してください。
|
||||
//
|
||||
// Other
|
||||
//
|
||||
// APIクライアントでは開発時のデバッグ出力が可能です。
|
||||
// 以下のようにTraceModeフラグをtrueに設定した上でAPI呼び出しを行うと、標準出力へトレースログが出力されます。
|
||||
//
|
||||
// client.TraceMode = true
|
||||
//
|
||||
package api
|
79
vendor/github.com/sacloud/libsacloud/api/error.go
generated
vendored
Normal file
79
vendor/github.com/sacloud/libsacloud/api/error.go
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
// Error APIコール時のエラー情報
|
||||
type Error interface {
|
||||
// errorインターフェースを内包
|
||||
error
|
||||
|
||||
// エラー発生時のレスポンスコード
|
||||
ResponseCode() int
|
||||
|
||||
// エラーコード
|
||||
Code() string
|
||||
|
||||
// エラー発生時のメッセージ
|
||||
Message() string
|
||||
|
||||
// エラー追跡用シリアルコード
|
||||
Serial() string
|
||||
|
||||
// エラー(オリジナル)
|
||||
OrigErr() *sacloud.ResultErrorValue
|
||||
}
|
||||
|
||||
// NewError APIコール時のエラー情報
|
||||
func NewError(responseCode int, err *sacloud.ResultErrorValue) Error {
|
||||
return &apiError{
|
||||
responseCode: responseCode,
|
||||
origErr: err,
|
||||
}
|
||||
}
|
||||
|
||||
type apiError struct {
|
||||
responseCode int
|
||||
origErr *sacloud.ResultErrorValue
|
||||
}
|
||||
|
||||
// Error errorインターフェース
|
||||
func (e *apiError) Error() string {
|
||||
return fmt.Sprintf("Error in response: %#v", e.origErr)
|
||||
}
|
||||
|
||||
// ResponseCode エラー発生時のレスポンスコード
|
||||
func (e *apiError) ResponseCode() int {
|
||||
return e.responseCode
|
||||
}
|
||||
|
||||
// Code エラーコード
|
||||
func (e *apiError) Code() string {
|
||||
if e.origErr != nil {
|
||||
return e.origErr.ErrorCode
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Message エラー発生時のメッセージ(
|
||||
func (e *apiError) Message() string {
|
||||
if e.origErr != nil {
|
||||
return e.origErr.ErrorMessage
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Serial エラー追跡用シリアルコード
|
||||
func (e *apiError) Serial() string {
|
||||
if e.origErr != nil {
|
||||
return e.origErr.Serial
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// OrigErr エラー(オリジナル)
|
||||
func (e *apiError) OrigErr() *sacloud.ResultErrorValue {
|
||||
return e.origErr
|
||||
}
|
202
vendor/github.com/sacloud/libsacloud/api/gslb.go
generated
vendored
Normal file
202
vendor/github.com/sacloud/libsacloud/api/gslb.go
generated
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
// "strings"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
//HACK: さくらのAPI側仕様: CommonServiceItemsの内容によってJSONフォーマットが異なるため
|
||||
// DNS/GSLB/シンプル監視それぞれでリクエスト/レスポンスデータ型を定義する。
|
||||
|
||||
// SearchGSLBResponse GSLB検索レスポンス
|
||||
type SearchGSLBResponse struct {
|
||||
// Total 総件数
|
||||
Total int `json:",omitempty"`
|
||||
// From ページング開始位置
|
||||
From int `json:",omitempty"`
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// CommonServiceGSLBItems GSLBリスト
|
||||
CommonServiceGSLBItems []sacloud.GSLB `json:"CommonServiceItems,omitempty"`
|
||||
}
|
||||
|
||||
type gslbRequest struct {
|
||||
CommonServiceGSLBItem *sacloud.GSLB `json:"CommonServiceItem,omitempty"`
|
||||
From int `json:",omitempty"`
|
||||
Count int `json:",omitempty"`
|
||||
Sort []string `json:",omitempty"`
|
||||
Filter map[string]interface{} `json:",omitempty"`
|
||||
Exclude []string `json:",omitempty"`
|
||||
Include []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type gslbResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
*sacloud.GSLB `json:"CommonServiceItem,omitempty"`
|
||||
}
|
||||
|
||||
// GSLBAPI GSLB API
|
||||
type GSLBAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewGSLBAPI GSLB API作成
|
||||
func NewGSLBAPI(client *Client) *GSLBAPI {
|
||||
return &GSLBAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "commonserviceitem"
|
||||
},
|
||||
FuncBaseSearchCondition: func() *sacloud.Request {
|
||||
res := &sacloud.Request{}
|
||||
res.AddFilter("Provider.Class", "gslb")
|
||||
return res
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Find 検索
|
||||
func (api *GSLBAPI) Find() (*SearchGSLBResponse, error) {
|
||||
|
||||
data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res SearchGSLBResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (api *GSLBAPI) request(f func(*gslbResponse) error) (*sacloud.GSLB, error) {
|
||||
res := &gslbResponse{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.GSLB, nil
|
||||
}
|
||||
|
||||
func (api *GSLBAPI) createRequest(value *sacloud.GSLB) *gslbResponse {
|
||||
return &gslbResponse{GSLB: value}
|
||||
}
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *GSLBAPI) New(name string) *sacloud.GSLB {
|
||||
return sacloud.CreateNewGSLB(name)
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *GSLBAPI) Create(value *sacloud.GSLB) (*sacloud.GSLB, error) {
|
||||
return api.request(func(res *gslbResponse) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *GSLBAPI) Read(id int64) (*sacloud.GSLB, error) {
|
||||
return api.request(func(res *gslbResponse) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *GSLBAPI) Update(id int64, value *sacloud.GSLB) (*sacloud.GSLB, error) {
|
||||
return api.request(func(res *gslbResponse) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *GSLBAPI) Delete(id int64) (*sacloud.GSLB, error) {
|
||||
return api.request(func(res *gslbResponse) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// SetupGSLBRecord GSLB配下にサーバー追加
|
||||
func (api *GSLBAPI) SetupGSLBRecord(gslbName string, ip string) ([]string, error) {
|
||||
|
||||
gslbItem, err := api.findOrCreateBy(gslbName)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gslbItem.Settings.GSLB.AddServer(ip)
|
||||
res, err := api.updateGSLBServers(gslbItem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gslbItem.ID == sacloud.EmptyID {
|
||||
return []string{res.Status.FQDN}, nil
|
||||
}
|
||||
return nil, nil
|
||||
|
||||
}
|
||||
|
||||
// DeleteGSLBServer GSLB配下のサーバー削除
|
||||
func (api *GSLBAPI) DeleteGSLBServer(gslbName string, ip string) error {
|
||||
gslbItem, err := api.findOrCreateBy(gslbName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gslbItem.Settings.GSLB.DeleteServer(ip)
|
||||
|
||||
if gslbItem.HasGSLBServer() {
|
||||
_, err = api.updateGSLBServers(gslbItem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
_, err = api.Delete(gslbItem.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (api *GSLBAPI) findOrCreateBy(gslbName string) (*sacloud.GSLB, error) {
|
||||
|
||||
req := &sacloud.Request{}
|
||||
req.AddFilter("Name", gslbName)
|
||||
res, err := api.Find()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//すでに登録されている場合
|
||||
var gslbItem *sacloud.GSLB
|
||||
if res.Count > 0 {
|
||||
gslbItem = &res.CommonServiceGSLBItems[0]
|
||||
} else {
|
||||
gslbItem = sacloud.CreateNewGSLB(gslbName)
|
||||
}
|
||||
|
||||
return gslbItem, nil
|
||||
}
|
||||
|
||||
func (api *GSLBAPI) updateGSLBServers(gslbItem *sacloud.GSLB) (*sacloud.GSLB, error) {
|
||||
|
||||
var item *sacloud.GSLB
|
||||
var err error
|
||||
|
||||
if gslbItem.ID == sacloud.EmptyID {
|
||||
item, err = api.Create(gslbItem)
|
||||
} else {
|
||||
item, err = api.Update(gslbItem.ID, gslbItem)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return item, nil
|
||||
}
|
238
vendor/github.com/sacloud/libsacloud/api/gslb_gen.go
generated
vendored
Normal file
238
vendor/github.com/sacloud/libsacloud/api/gslb_gen.go
generated
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [GSLBAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *GSLBAPI) Reset() *GSLBAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *GSLBAPI) Offset(offset int) *GSLBAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *GSLBAPI) Limit(limit int) *GSLBAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *GSLBAPI) Include(key string) *GSLBAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *GSLBAPI) Exclude(key string) *GSLBAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *GSLBAPI) FilterBy(key string, value interface{}) *GSLBAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *GSLBAPI) FilterMultiBy(key string, value interface{}) *GSLBAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *GSLBAPI) WithNameLike(name string) *GSLBAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *GSLBAPI) WithTag(tag string) *GSLBAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *GSLBAPI) WithTags(tags []string) *GSLBAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *GSLBAPI) WithSizeGib(size int) *GSLBAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *GSLBAPI) WithSharedScope() *GSLBAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *GSLBAPI) WithUserScope() *GSLBAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *GSLBAPI) SortBy(key string, reverse bool) *GSLBAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *GSLBAPI) SortByName(reverse bool) *GSLBAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *GSLBAPI) SortBySize(reverse bool) *GSLBAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *GSLBAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *GSLBAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *GSLBAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *GSLBAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *GSLBAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *GSLBAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *GSLBAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *GSLBAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *GSLBAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *GSLBAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *GSLBAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *GSLBAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *GSLBAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *GSLBAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *GSLBAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *GSLBAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *GSLBAPI) New() *sacloud.GSLB {
|
||||
// return &sacloud.GSLB{}
|
||||
// }
|
||||
|
||||
// func (api *GSLBAPI) Create(value *sacloud.GSLB) (*sacloud.GSLB, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *GSLBAPI) Read(id string) (*sacloud.GSLB, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *GSLBAPI) Update(id string, value *sacloud.GSLB) (*sacloud.GSLB, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *GSLBAPI) Delete(id string) (*sacloud.GSLB, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *GSLBAPI) setStateValue(setFunc func(*sacloud.Request)) *GSLBAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *GSLBAPI) request(f func(*sacloud.Response) error) (*sacloud.GSLB, error) {
|
||||
// res := &sacloud.Response{}
|
||||
// err := f(res)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return res.GSLB, nil
|
||||
//}
|
||||
//
|
||||
//func (api *GSLBAPI) createRequest(value *sacloud.GSLB) *sacloud.Request {
|
||||
// req := &sacloud.Request{}
|
||||
// req.GSLB = value
|
||||
// return req
|
||||
//}
|
31
vendor/github.com/sacloud/libsacloud/api/icon.go
generated
vendored
Normal file
31
vendor/github.com/sacloud/libsacloud/api/icon.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
package api
|
||||
|
||||
import "github.com/sacloud/libsacloud/sacloud"
|
||||
|
||||
// IconAPI アイコンAPI
|
||||
type IconAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewIconAPI アイコンAPI作成
|
||||
func NewIconAPI(client *Client) *IconAPI {
|
||||
return &IconAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "icon"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// GetImage アイコン画像データ(BASE64文字列)取得
|
||||
func (api *IconAPI) GetImage(id int64, size string) (*sacloud.Image, error) {
|
||||
|
||||
res := &sacloud.Response{}
|
||||
err := api.read(id, map[string]string{"Size": size}, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Image, nil
|
||||
}
|
247
vendor/github.com/sacloud/libsacloud/api/icon_gen.go
generated
vendored
Normal file
247
vendor/github.com/sacloud/libsacloud/api/icon_gen.go
generated
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [IconAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *IconAPI) Reset() *IconAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *IconAPI) Offset(offset int) *IconAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *IconAPI) Limit(limit int) *IconAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *IconAPI) Include(key string) *IconAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *IconAPI) Exclude(key string) *IconAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *IconAPI) FilterBy(key string, value interface{}) *IconAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *IconAPI) FilterMultiBy(key string, value interface{}) *IconAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *IconAPI) WithNameLike(name string) *IconAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *IconAPI) WithTag(tag string) *IconAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *IconAPI) WithTags(tags []string) *IconAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *IconAPI) WithSizeGib(size int) *IconAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// WithSharedScope 公開スコープ条件
|
||||
func (api *IconAPI) WithSharedScope() *IconAPI {
|
||||
api.FilterBy("Scope", "shared")
|
||||
return api
|
||||
}
|
||||
|
||||
// WithUserScope ユーザースコープ条件
|
||||
func (api *IconAPI) WithUserScope() *IconAPI {
|
||||
api.FilterBy("Scope", "user")
|
||||
return api
|
||||
}
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *IconAPI) SortBy(key string, reverse bool) *IconAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *IconAPI) SortByName(reverse bool) *IconAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *IconAPI) SortBySize(reverse bool) *IconAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *IconAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *IconAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *IconAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *IconAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *IconAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *IconAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *IconAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *IconAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *IconAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *IconAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *IconAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// SetSharedScope 公開スコープ条件
|
||||
func (api *IconAPI) SetSharedScope() {
|
||||
api.FilterBy("Scope", "shared")
|
||||
}
|
||||
|
||||
// SetUserScope ユーザースコープ条件
|
||||
func (api *IconAPI) SetUserScope() {
|
||||
api.FilterBy("Scope", "user")
|
||||
}
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *IconAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *IconAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *IconAPI) SortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *IconAPI) New() *sacloud.Icon {
|
||||
return &sacloud.Icon{}
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *IconAPI) Create(value *sacloud.Icon) (*sacloud.Icon, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *IconAPI) Read(id int64) (*sacloud.Icon, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *IconAPI) Update(id int64, value *sacloud.Icon) (*sacloud.Icon, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *IconAPI) Delete(id int64) (*sacloud.Icon, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *IconAPI) setStateValue(setFunc func(*sacloud.Request)) *IconAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *IconAPI) request(f func(*sacloud.Response) error) (*sacloud.Icon, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Icon, nil
|
||||
}
|
||||
|
||||
func (api *IconAPI) createRequest(value *sacloud.Icon) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.Icon = value
|
||||
return req
|
||||
}
|
83
vendor/github.com/sacloud/libsacloud/api/interface.go
generated
vendored
Normal file
83
vendor/github.com/sacloud/libsacloud/api/interface.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
// InterfaceAPI インターフェースAPI
|
||||
type InterfaceAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewInterfaceAPI インターフェースAPI作成
|
||||
func NewInterfaceAPI(client *Client) *InterfaceAPI {
|
||||
return &InterfaceAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "interface"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// CreateAndConnectToServer 新規作成しサーバーへ接続する
|
||||
func (api *InterfaceAPI) CreateAndConnectToServer(serverID int64) (*sacloud.Interface, error) {
|
||||
iface := api.New()
|
||||
iface.Server = &sacloud.Server{
|
||||
// Resource
|
||||
Resource: &sacloud.Resource{ID: serverID},
|
||||
}
|
||||
return api.Create(iface)
|
||||
}
|
||||
|
||||
// ConnectToSwitch スイッチへ接続する
|
||||
func (api *InterfaceAPI) ConnectToSwitch(interfaceID int64, switchID int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/to/switch/%d", api.getResourceURL(), interfaceID, switchID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// ConnectToSharedSegment 共有セグメントへ接続する
|
||||
func (api *InterfaceAPI) ConnectToSharedSegment(interfaceID int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/to/switch/shared", api.getResourceURL(), interfaceID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// DisconnectFromSwitch スイッチと切断する
|
||||
func (api *InterfaceAPI) DisconnectFromSwitch(interfaceID int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/to/switch", api.getResourceURL(), interfaceID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Monitor アクティビティーモニター取得
|
||||
func (api *InterfaceAPI) Monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.monitor(id, body)
|
||||
}
|
||||
|
||||
// ConnectToPacketFilter パケットフィルター適用
|
||||
func (api *InterfaceAPI) ConnectToPacketFilter(interfaceID int64, packetFilterID int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("/%s/%d/to/packetfilter/%d", api.getResourceURL(), interfaceID, packetFilterID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// DisconnectFromPacketFilter パケットフィルター切断
|
||||
func (api *InterfaceAPI) DisconnectFromPacketFilter(interfaceID int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("/%s/%d/to/packetfilter", api.getResourceURL(), interfaceID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
243
vendor/github.com/sacloud/libsacloud/api/interface_gen.go
generated
vendored
Normal file
243
vendor/github.com/sacloud/libsacloud/api/interface_gen.go
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [InterfaceAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *InterfaceAPI) Reset() *InterfaceAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *InterfaceAPI) Offset(offset int) *InterfaceAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *InterfaceAPI) Limit(limit int) *InterfaceAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *InterfaceAPI) Include(key string) *InterfaceAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *InterfaceAPI) Exclude(key string) *InterfaceAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *InterfaceAPI) FilterBy(key string, value interface{}) *InterfaceAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *InterfaceAPI) FilterMultiBy(key string, value interface{}) *InterfaceAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *InterfaceAPI) WithNameLike(name string) *InterfaceAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *InterfaceAPI) WithTag(tag string) *InterfaceAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *InterfaceAPI) WithTags(tags []string) *InterfaceAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *InterfaceAPI) WithSizeGib(size int) *InterfaceAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *InterfaceAPI) WithSharedScope() *InterfaceAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *InterfaceAPI) WithUserScope() *InterfaceAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *InterfaceAPI) SortBy(key string, reverse bool) *InterfaceAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *InterfaceAPI) SortByName(reverse bool) *InterfaceAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *InterfaceAPI) SortBySize(reverse bool) *InterfaceAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *InterfaceAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *InterfaceAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *InterfaceAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *InterfaceAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *InterfaceAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *InterfaceAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *InterfaceAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *InterfaceAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *InterfaceAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *InterfaceAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *InterfaceAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *InterfaceAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *InterfaceAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *InterfaceAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *InterfaceAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *InterfaceAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *InterfaceAPI) New() *sacloud.Interface {
|
||||
return &sacloud.Interface{}
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *InterfaceAPI) Create(value *sacloud.Interface) (*sacloud.Interface, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *InterfaceAPI) Read(id int64) (*sacloud.Interface, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *InterfaceAPI) Update(id int64, value *sacloud.Interface) (*sacloud.Interface, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *InterfaceAPI) Delete(id int64) (*sacloud.Interface, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *InterfaceAPI) setStateValue(setFunc func(*sacloud.Request)) *InterfaceAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *InterfaceAPI) request(f func(*sacloud.Response) error) (*sacloud.Interface, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Interface, nil
|
||||
}
|
||||
|
||||
func (api *InterfaceAPI) createRequest(value *sacloud.Interface) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.Interface = value
|
||||
return req
|
||||
}
|
143
vendor/github.com/sacloud/libsacloud/api/internet.go
generated
vendored
Normal file
143
vendor/github.com/sacloud/libsacloud/api/internet.go
generated
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"time"
|
||||
)
|
||||
|
||||
// InternetAPI ルーターAPI
|
||||
type InternetAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewInternetAPI ルーターAPI作成
|
||||
func NewInternetAPI(client *Client) *InternetAPI {
|
||||
return &InternetAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "internet"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateBandWidth 帯域幅更新
|
||||
func (api *InternetAPI) UpdateBandWidth(id int64, bandWidth int) (*sacloud.Internet, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/bandwidth", api.getResourceURL(), id)
|
||||
body = &sacloud.Request{}
|
||||
)
|
||||
body.Internet = &sacloud.Internet{BandWidthMbps: bandWidth}
|
||||
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.baseAPI.request(method, uri, body, res)
|
||||
})
|
||||
}
|
||||
|
||||
// AddSubnet IPアドレスブロックの追加割り当て
|
||||
func (api *InternetAPI) AddSubnet(id int64, nwMaskLen int, nextHop string) (*sacloud.Subnet, error) {
|
||||
var (
|
||||
method = "POST"
|
||||
uri = fmt.Sprintf("%s/%d/subnet", api.getResourceURL(), id)
|
||||
)
|
||||
body := &map[string]interface{}{
|
||||
"NetworkMaskLen": nwMaskLen,
|
||||
"NextHop": nextHop,
|
||||
}
|
||||
|
||||
res := &sacloud.Response{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Subnet, nil
|
||||
}
|
||||
|
||||
// UpdateSubnet IPアドレスブロックの更新
|
||||
func (api *InternetAPI) UpdateSubnet(id int64, subnetID int64, nextHop string) (*sacloud.Subnet, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/subnet/%d", api.getResourceURL(), id, subnetID)
|
||||
)
|
||||
body := &map[string]interface{}{
|
||||
"NextHop": nextHop,
|
||||
}
|
||||
|
||||
res := &sacloud.Response{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Subnet, nil
|
||||
}
|
||||
|
||||
// DeleteSubnet IPアドレスブロックの削除
|
||||
func (api *InternetAPI) DeleteSubnet(id int64, subnetID int64) (*sacloud.ResultFlagValue, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/subnet/%d", api.getResourceURL(), id, subnetID)
|
||||
)
|
||||
|
||||
res := &sacloud.ResultFlagValue{}
|
||||
err := api.baseAPI.request(method, uri, nil, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// EnableIPv6 IPv6有効化
|
||||
func (api *InternetAPI) EnableIPv6(id int64) (*sacloud.IPv6Net, error) {
|
||||
var (
|
||||
method = "POST"
|
||||
uri = fmt.Sprintf("%s/%d/ipv6net", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
res := &sacloud.Response{}
|
||||
err := api.baseAPI.request(method, uri, nil, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.IPv6Net, nil
|
||||
}
|
||||
|
||||
// DisableIPv6 IPv6無効化
|
||||
func (api *InternetAPI) DisableIPv6(id int64, ipv6NetID int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/ipv6net/%d", api.getResourceURL(), id, ipv6NetID)
|
||||
)
|
||||
|
||||
res := &sacloud.Response{}
|
||||
err := api.baseAPI.request(method, uri, nil, res)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// SleepWhileCreating 作成完了まで待機(リトライ10)
|
||||
func (api *InternetAPI) SleepWhileCreating(id int64, timeout time.Duration) error {
|
||||
handler := waitingForReadFunc(func() (interface{}, error) {
|
||||
return api.Read(id)
|
||||
}, 10) // 作成直後はReadが404を返すことがあるためリトライ
|
||||
return blockingPoll(handler, timeout)
|
||||
|
||||
}
|
||||
|
||||
// RetrySleepWhileCreating 作成完了まで待機 作成直後はReadが404を返すことがあるためmaxRetryまでリトライする
|
||||
func (api *InternetAPI) RetrySleepWhileCreating(id int64, timeout time.Duration, maxRetry int) error {
|
||||
handler := waitingForReadFunc(func() (interface{}, error) {
|
||||
return api.Read(id)
|
||||
}, maxRetry)
|
||||
return blockingPoll(handler, timeout)
|
||||
|
||||
}
|
||||
|
||||
// Monitor アクティビティーモニター取得
|
||||
func (api *InternetAPI) Monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.monitor(id, body)
|
||||
}
|
243
vendor/github.com/sacloud/libsacloud/api/internet_gen.go
generated
vendored
Normal file
243
vendor/github.com/sacloud/libsacloud/api/internet_gen.go
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [InternetAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *InternetAPI) Reset() *InternetAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *InternetAPI) Offset(offset int) *InternetAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *InternetAPI) Limit(limit int) *InternetAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *InternetAPI) Include(key string) *InternetAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *InternetAPI) Exclude(key string) *InternetAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *InternetAPI) FilterBy(key string, value interface{}) *InternetAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *InternetAPI) FilterMultiBy(key string, value interface{}) *InternetAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *InternetAPI) WithNameLike(name string) *InternetAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *InternetAPI) WithTag(tag string) *InternetAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *InternetAPI) WithTags(tags []string) *InternetAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *InternetAPI) WithSizeGib(size int) *InternetAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *InternetAPI) WithSharedScope() *InternetAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *InternetAPI) WithUserScope() *InternetAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *InternetAPI) SortBy(key string, reverse bool) *InternetAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *InternetAPI) SortByName(reverse bool) *InternetAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *InternetAPI) SortBySize(reverse bool) *InternetAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *InternetAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *InternetAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *InternetAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *InternetAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *InternetAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *InternetAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *InternetAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *InternetAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *InternetAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *InternetAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *InternetAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *InternetAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *InternetAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *InternetAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *InternetAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *InternetAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *InternetAPI) New() *sacloud.Internet {
|
||||
return &sacloud.Internet{}
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *InternetAPI) Create(value *sacloud.Internet) (*sacloud.Internet, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *InternetAPI) Read(id int64) (*sacloud.Internet, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *InternetAPI) Update(id int64, value *sacloud.Internet) (*sacloud.Internet, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *InternetAPI) Delete(id int64) (*sacloud.Internet, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *InternetAPI) setStateValue(setFunc func(*sacloud.Request)) *InternetAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *InternetAPI) request(f func(*sacloud.Response) error) (*sacloud.Internet, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Internet, nil
|
||||
}
|
||||
|
||||
func (api *InternetAPI) createRequest(value *sacloud.Internet) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.Internet = value
|
||||
return req
|
||||
}
|
56
vendor/github.com/sacloud/libsacloud/api/ipaddress.go
generated
vendored
Normal file
56
vendor/github.com/sacloud/libsacloud/api/ipaddress.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
// IPAddressAPI IPアドレスAPI
|
||||
type IPAddressAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewIPAddressAPI IPアドレスAPI新規作成
|
||||
func NewIPAddressAPI(client *Client) *IPAddressAPI {
|
||||
return &IPAddressAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "ipaddress"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *IPAddressAPI) Read(ip string) (*sacloud.IPAddress, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%s", api.getResourceURL(), ip)
|
||||
)
|
||||
|
||||
return api.baseAPI.request(method, uri, nil, res)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Update 更新(ホスト名逆引き設定)
|
||||
func (api *IPAddressAPI) Update(ip string, hostName string) (*sacloud.IPAddress, error) {
|
||||
|
||||
type request struct {
|
||||
// IPAddress
|
||||
IPAddress map[string]string
|
||||
}
|
||||
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%s", api.getResourceURL(), ip)
|
||||
body = &request{IPAddress: map[string]string{}}
|
||||
)
|
||||
body.IPAddress["HostName"] = hostName
|
||||
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.baseAPI.request(method, uri, body, res)
|
||||
})
|
||||
}
|
231
vendor/github.com/sacloud/libsacloud/api/ipaddress_gen.go
generated
vendored
Normal file
231
vendor/github.com/sacloud/libsacloud/api/ipaddress_gen.go
generated
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [IPAddressAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *IPAddressAPI) Reset() *IPAddressAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *IPAddressAPI) Offset(offset int) *IPAddressAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *IPAddressAPI) Limit(limit int) *IPAddressAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *IPAddressAPI) Include(key string) *IPAddressAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *IPAddressAPI) Exclude(key string) *IPAddressAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルタ
|
||||
func (api *IPAddressAPI) FilterBy(key string, value interface{}) *IPAddressAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *IPAddressAPI) FilterMultiBy(key string, value interface{}) *IPAddressAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *IPAddressAPI) WithNameLike(name string) *IPAddressAPI {
|
||||
// return api.FilterBy("Name", name)
|
||||
//}
|
||||
|
||||
//func (api *IPAddressAPI) WithTag(tag string) *IPAddressAPI {
|
||||
// return api.FilterBy("Tags.Name", tag)
|
||||
//}
|
||||
//func (api *IPAddressAPI) WithTags(tags []string) *IPAddressAPI {
|
||||
// return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
//}
|
||||
//
|
||||
//func (api *IPAddressAPI) WithSizeGib(size int) *IPAddressAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
//}
|
||||
//
|
||||
//func (api *IPAddressAPI) WithSharedScope() *IPAddressAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
//}
|
||||
//
|
||||
//func (api *IPAddressAPI) WithUserScope() *IPAddressAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
//}
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *IPAddressAPI) SortBy(key string, reverse bool) *IPAddressAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
//// SortByName 名称でのソート
|
||||
//func (api *IPAddressAPI) SortByName(reverse bool) *IPAddressAPI {
|
||||
// api.sortByName(reverse)
|
||||
// return api
|
||||
//}
|
||||
|
||||
//func (api *IPAddressAPI) SortBySize(reverse bool) *IPAddressAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
//}
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *IPAddressAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *IPAddressAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *IPAddressAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *IPAddressAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *IPAddressAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルタ
|
||||
func (api *IPAddressAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *IPAddressAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
//func (api *IPAddressAPI) SetNameLike(name string) {
|
||||
// api.FilterBy("Name", name)
|
||||
//}
|
||||
|
||||
//func (api *IPAddressAPI) SetTag(tag string) {
|
||||
// api.FilterBy("Tags.Name", tag)
|
||||
//}
|
||||
//func (api *IPAddressAPI) SetTags(tags []string) {
|
||||
// api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
//}
|
||||
//
|
||||
//func (api *IPAddressAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
//}
|
||||
//
|
||||
//func (api *IPAddressAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
//}
|
||||
//
|
||||
//func (api *IPAddressAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
//}
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *IPAddressAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
//// SetSortByName 名称でのソート
|
||||
//func (api *IPAddressAPI) SetSortByName(reverse bool) {
|
||||
// api.sortByName(reverse)
|
||||
//}
|
||||
|
||||
//func (api *IPAddressAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
//}
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
//func (api *IPAddressAPI) Create(value *sacloud.IPAddress) (*sacloud.IPAddress, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
//}
|
||||
|
||||
//func (api *IPAddressAPI) Read(id int64) (*sacloud.IPAddress, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
//}
|
||||
|
||||
//func (api *IPAddressAPI) Update(id int64, value *sacloud.IPAddress) (*sacloud.IPAddress, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
//}
|
||||
//
|
||||
//func (api *IPAddressAPI) Delete(id int64) (*sacloud.IPAddress, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
//}
|
||||
//
|
||||
//func (api *IPAddressAPI) New() *sacloud.IPAddress {
|
||||
// return &sacloud.IPAddress{
|
||||
// }
|
||||
//}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *IPAddressAPI) setStateValue(setFunc func(*sacloud.Request)) *IPAddressAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *IPAddressAPI) request(f func(*sacloud.Response) error) (*sacloud.IPAddress, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.IPAddress, nil
|
||||
}
|
||||
|
||||
func (api *IPAddressAPI) createRequest(value *sacloud.IPAddress) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.IPAddress = value
|
||||
return req
|
||||
}
|
96
vendor/github.com/sacloud/libsacloud/api/ipv6addr.go
generated
vendored
Normal file
96
vendor/github.com/sacloud/libsacloud/api/ipv6addr.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
// IPv6AddrAPI IPv6アドレスAPI
|
||||
type IPv6AddrAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewIPv6AddrAPI IPv6アドレスAPI新規作成
|
||||
func NewIPv6AddrAPI(client *Client) *IPv6AddrAPI {
|
||||
return &IPv6AddrAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "ipv6addr"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *IPv6AddrAPI) Read(ip string) (*sacloud.IPv6Addr, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%s", api.getResourceURL(), ip)
|
||||
)
|
||||
|
||||
return api.baseAPI.request(method, uri, nil, res)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *IPv6AddrAPI) Create(ip string, hostName string) (*sacloud.IPv6Addr, error) {
|
||||
|
||||
type request struct {
|
||||
// IPv6Addr
|
||||
IPv6Addr map[string]string
|
||||
}
|
||||
|
||||
var (
|
||||
method = "POST"
|
||||
uri = api.getResourceURL()
|
||||
body = &request{IPv6Addr: map[string]string{}}
|
||||
)
|
||||
body.IPv6Addr["IPv6Addr"] = ip
|
||||
body.IPv6Addr["HostName"] = hostName
|
||||
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.baseAPI.request(method, uri, body, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *IPv6AddrAPI) Update(ip string, hostName string) (*sacloud.IPv6Addr, error) {
|
||||
|
||||
type request struct {
|
||||
// IPv6Addr
|
||||
IPv6Addr map[string]string
|
||||
}
|
||||
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%s", api.getResourceURL(), ip)
|
||||
body = &request{IPv6Addr: map[string]string{}}
|
||||
)
|
||||
body.IPv6Addr["HostName"] = hostName
|
||||
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.baseAPI.request(method, uri, body, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *IPv6AddrAPI) Delete(ip string) (*sacloud.IPv6Addr, error) {
|
||||
|
||||
type request struct {
|
||||
// IPv6Addr
|
||||
IPv6Addr map[string]string
|
||||
}
|
||||
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%s", api.getResourceURL(), ip)
|
||||
body = &request{IPv6Addr: map[string]string{}}
|
||||
)
|
||||
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.baseAPI.request(method, uri, body, res)
|
||||
})
|
||||
}
|
232
vendor/github.com/sacloud/libsacloud/api/ipv6addr_gen.go
generated
vendored
Normal file
232
vendor/github.com/sacloud/libsacloud/api/ipv6addr_gen.go
generated
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [IPv6AddrAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *IPv6AddrAPI) Reset() *IPv6AddrAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *IPv6AddrAPI) Offset(offset int) *IPv6AddrAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *IPv6AddrAPI) Limit(limit int) *IPv6AddrAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *IPv6AddrAPI) Include(key string) *IPv6AddrAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *IPv6AddrAPI) Exclude(key string) *IPv6AddrAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *IPv6AddrAPI) FilterBy(key string, value interface{}) *IPv6AddrAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *IPv6AddrAPI) FilterMultiBy(key string, value interface{}) *IPv6AddrAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *IPv6AddrAPI) WithNameLike(name string) *IPv6AddrAPI {
|
||||
// return api.FilterBy("Name", name)
|
||||
//}
|
||||
|
||||
//func (api *IPv6AddrAPI) WithTag(tag string) *IPv6AddrAPI {
|
||||
// return api.FilterBy("Tags.Name", tag)
|
||||
//}
|
||||
//func (api *IPv6AddrAPI) WithTags(tags []string) *IPv6AddrAPI {
|
||||
// return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
//}
|
||||
//
|
||||
//func (api *IPv6AddrAPI) WithSizeGib(size int) *IPv6AddrAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
//}
|
||||
//
|
||||
//func (api *IPv6AddrAPI) WithSharedScope() *IPv6AddrAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
//}
|
||||
//
|
||||
//func (api *IPv6AddrAPI) WithUserScope() *IPv6AddrAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
//}
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *IPv6AddrAPI) SortBy(key string, reverse bool) *IPv6AddrAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
//// SortByName
|
||||
//func (api *IPv6AddrAPI) SortByName(reverse bool) *IPv6AddrAPI {
|
||||
// api.sortByName(reverse)
|
||||
// return api
|
||||
//}
|
||||
|
||||
//func (api *IPv6AddrAPI) SortBySize(reverse bool) *IPv6AddrAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
//}
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *IPv6AddrAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *IPv6AddrAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *IPv6AddrAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *IPv6AddrAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *IPv6AddrAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *IPv6AddrAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *IPv6AddrAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
//func (api *IPv6AddrAPI) SetNameLike(name string) {
|
||||
//}
|
||||
|
||||
//func (api *IPv6AddrAPI) SetTag(tag string) {
|
||||
// api.FilterBy("Tags.Name", tag)
|
||||
//}
|
||||
//func (api *IPv6AddrAPI) SetTags(tags []string) {
|
||||
// api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
//}
|
||||
//
|
||||
//func (api *IPv6AddrAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
//}
|
||||
//
|
||||
//func (api *IPv6AddrAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
//}
|
||||
//
|
||||
//func (api *IPv6AddrAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
//}
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *IPv6AddrAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
//// SetSortByName
|
||||
//func (api *IPv6AddrAPI) SetSortByName(reverse bool) {
|
||||
// api.sortByName(reverse)
|
||||
//}
|
||||
|
||||
//func (api *IPv6AddrAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
//}
|
||||
|
||||
/************************************************
|
||||
// To
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
//func (api *IPv6AddrAPI) Create(value *sacloud.IPv6Addr) (*sacloud.IPv6Addr, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
//}
|
||||
|
||||
//func (api *IPv6AddrAPI) Read(id int64) (*sacloud.IPv6Addr, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
//}
|
||||
|
||||
//func (api *IPv6AddrAPI) Update(id int64, value *sacloud.IPv6Addr) (*sacloud.IPv6Addr, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
//}
|
||||
//
|
||||
//func (api *IPv6AddrAPI) Delete(id int64) (*sacloud.IPv6Addr, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
//}
|
||||
//
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *IPv6AddrAPI) New() *sacloud.IPv6Addr {
|
||||
return sacloud.CreateNewIPv6Addr()
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *IPv6AddrAPI) setStateValue(setFunc func(*sacloud.Request)) *IPv6AddrAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *IPv6AddrAPI) request(f func(*sacloud.Response) error) (*sacloud.IPv6Addr, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.IPv6Addr, nil
|
||||
}
|
||||
|
||||
func (api *IPv6AddrAPI) createRequest(value *sacloud.IPv6Addr) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.IPv6Addr = value
|
||||
return req
|
||||
}
|
18
vendor/github.com/sacloud/libsacloud/api/ipv6net.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/ipv6net.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// IPv6NetAPI IPv6ネットワークAPI
|
||||
type IPv6NetAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewIPv6NetAPI IPv6ネットワークAPI作成
|
||||
func NewIPv6NetAPI(client *Client) *IPv6NetAPI {
|
||||
return &IPv6NetAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "ipv6net"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
229
vendor/github.com/sacloud/libsacloud/api/ipv6net_gen.go
generated
vendored
Normal file
229
vendor/github.com/sacloud/libsacloud/api/ipv6net_gen.go
generated
vendored
Normal file
@ -0,0 +1,229 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [IPv6NetAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のクリア
|
||||
func (api *IPv6NetAPI) Reset() *IPv6NetAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *IPv6NetAPI) Offset(offset int) *IPv6NetAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *IPv6NetAPI) Limit(limit int) *IPv6NetAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *IPv6NetAPI) Include(key string) *IPv6NetAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *IPv6NetAPI) Exclude(key string) *IPv6NetAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *IPv6NetAPI) FilterBy(key string, value interface{}) *IPv6NetAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *IPv6NetAPI) FilterMultiBy(key string, value interface{}) *IPv6NetAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *IPv6NetAPI) WithNameLike(name string) *IPv6NetAPI {
|
||||
// return api.FilterBy("Name", name)
|
||||
//}
|
||||
//
|
||||
//func (api *IPv6NetAPI) WithTag(tag string) *IPv6NetAPI {
|
||||
// return api.FilterBy("Tags.Name", tag)
|
||||
//}
|
||||
//func (api *IPv6NetAPI) WithTags(tags []string) *IPv6NetAPI {
|
||||
// return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
//}
|
||||
|
||||
// func (api *IPv6NetAPI) WithSizeGib(size int) *IPv6NetAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *IPv6NetAPI) WithSharedScope() *IPv6NetAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *IPv6NetAPI) WithUserScope() *IPv6NetAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *IPv6NetAPI) SortBy(key string, reverse bool) *IPv6NetAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *IPv6NetAPI) SortByName(reverse bool) *IPv6NetAPI {
|
||||
// api.sortByName(reverse)
|
||||
// return api
|
||||
//}
|
||||
|
||||
// func (api *IPv6NetAPI) SortBySize(reverse bool) *IPv6NetAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のクリア
|
||||
func (api *IPv6NetAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *IPv6NetAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *IPv6NetAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *IPv6NetAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *IPv6NetAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *IPv6NetAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *IPv6NetAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
//func (api *IPv6NetAPI) SetNameLike(name string) {
|
||||
// api.FilterBy("Name", name)
|
||||
//}
|
||||
//
|
||||
//func (api *IPv6NetAPI) SetTag(tag string) {
|
||||
// api.FilterBy("Tags.Name", tag)
|
||||
//}
|
||||
//func (api *IPv6NetAPI) SetTags(tags []string) {
|
||||
// api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
//}
|
||||
|
||||
// func (api *IPv6NetAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *IPv6NetAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *IPv6NetAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *IPv6NetAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
//func (api *IPv6NetAPI) SetSortByName(reverse bool) {
|
||||
// api.sortByName(reverse)
|
||||
//}
|
||||
|
||||
// func (api *IPv6NetAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
//func (api *IPv6NetAPI) New() *sacloud.IPv6Net {
|
||||
// return &sacloud.IPv6Net{}
|
||||
//}
|
||||
|
||||
//func (api *IPv6NetAPI) Create(value *sacloud.IPv6Net) (*sacloud.IPv6Net, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
//}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *IPv6NetAPI) Read(id int64) (*sacloud.IPv6Net, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
//func (api *IPv6NetAPI) Update(id int64, value *sacloud.IPv6Net) (*sacloud.IPv6Net, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
//}
|
||||
//
|
||||
//func (api *IPv6NetAPI) Delete(id int64) (*sacloud.IPv6Net, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
//}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *IPv6NetAPI) setStateValue(setFunc func(*sacloud.Request)) *IPv6NetAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *IPv6NetAPI) request(f func(*sacloud.Response) error) (*sacloud.IPv6Net, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.IPv6Net, nil
|
||||
}
|
||||
|
||||
func (api *IPv6NetAPI) createRequest(value *sacloud.IPv6Net) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.IPv6Net = value
|
||||
return req
|
||||
}
|
18
vendor/github.com/sacloud/libsacloud/api/license.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/license.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// LicenseAPI ライセンスAPI
|
||||
type LicenseAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewLicenseAPI ライセンスAPI作成
|
||||
func NewLicenseAPI(client *Client) *LicenseAPI {
|
||||
return &LicenseAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "license"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
243
vendor/github.com/sacloud/libsacloud/api/license_gen.go
generated
vendored
Normal file
243
vendor/github.com/sacloud/libsacloud/api/license_gen.go
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [LicenseAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *LicenseAPI) Reset() *LicenseAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *LicenseAPI) Offset(offset int) *LicenseAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *LicenseAPI) Limit(limit int) *LicenseAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *LicenseAPI) Include(key string) *LicenseAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *LicenseAPI) Exclude(key string) *LicenseAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *LicenseAPI) FilterBy(key string, value interface{}) *LicenseAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *LicenseAPI) FilterMultiBy(key string, value interface{}) *LicenseAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *LicenseAPI) WithNameLike(name string) *LicenseAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *LicenseAPI) WithTag(tag string) *LicenseAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *LicenseAPI) WithTags(tags []string) *LicenseAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *LicenseAPI) WithSizeGib(size int) *LicenseAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *LicenseAPI) WithSharedScope() *LicenseAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *LicenseAPI) WithUserScope() *LicenseAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *LicenseAPI) SortBy(key string, reverse bool) *LicenseAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *LicenseAPI) SortByName(reverse bool) *LicenseAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *LicenseAPI) SortBySize(reverse bool) *LicenseAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *LicenseAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *LicenseAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *LicenseAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *LicenseAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *LicenseAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *LicenseAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *LicenseAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *LicenseAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *LicenseAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *LicenseAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *LicenseAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *LicenseAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *LicenseAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *LicenseAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *LicenseAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *LicenseAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *LicenseAPI) New() *sacloud.License {
|
||||
return &sacloud.License{}
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *LicenseAPI) Create(value *sacloud.License) (*sacloud.License, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *LicenseAPI) Read(id int64) (*sacloud.License, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *LicenseAPI) Update(id int64, value *sacloud.License) (*sacloud.License, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *LicenseAPI) Delete(id int64) (*sacloud.License, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *LicenseAPI) setStateValue(setFunc func(*sacloud.Request)) *LicenseAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *LicenseAPI) request(f func(*sacloud.Response) error) (*sacloud.License, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.License, nil
|
||||
}
|
||||
|
||||
func (api *LicenseAPI) createRequest(value *sacloud.License) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.License = value
|
||||
return req
|
||||
}
|
232
vendor/github.com/sacloud/libsacloud/api/load_balancer.go
generated
vendored
Normal file
232
vendor/github.com/sacloud/libsacloud/api/load_balancer.go
generated
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"time"
|
||||
)
|
||||
|
||||
//HACK: さくらのAPI側仕様: Applianceの内容によってJSONフォーマットが異なるため
|
||||
// ロードバランサ/VPCルータそれぞれでリクエスト/レスポンスデータ型を定義する。
|
||||
|
||||
// SearchLoadBalancerResponse ロードバランサー検索レスポンス
|
||||
type SearchLoadBalancerResponse struct {
|
||||
// Total 総件数
|
||||
Total int `json:",omitempty"`
|
||||
// From ページング開始位置
|
||||
From int `json:",omitempty"`
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// LoadBalancers ロードバランサー リスト
|
||||
LoadBalancers []sacloud.LoadBalancer `json:"Appliances,omitempty"`
|
||||
}
|
||||
|
||||
type loadBalancerRequest struct {
|
||||
LoadBalancer *sacloud.LoadBalancer `json:"Appliance,omitempty"`
|
||||
From int `json:",omitempty"`
|
||||
Count int `json:",omitempty"`
|
||||
Sort []string `json:",omitempty"`
|
||||
Filter map[string]interface{} `json:",omitempty"`
|
||||
Exclude []string `json:",omitempty"`
|
||||
Include []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type loadBalancerResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
*sacloud.LoadBalancer `json:"Appliance,omitempty"`
|
||||
Success interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{}
|
||||
}
|
||||
|
||||
// LoadBalancerAPI ロードバランサーAPI
|
||||
type LoadBalancerAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewLoadBalancerAPI ロードバランサーAPI作成
|
||||
func NewLoadBalancerAPI(client *Client) *LoadBalancerAPI {
|
||||
return &LoadBalancerAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "appliance"
|
||||
},
|
||||
FuncBaseSearchCondition: func() *sacloud.Request {
|
||||
res := &sacloud.Request{}
|
||||
res.AddFilter("Class", "loadbalancer")
|
||||
return res
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Find 検索
|
||||
func (api *LoadBalancerAPI) Find() (*SearchLoadBalancerResponse, error) {
|
||||
data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res SearchLoadBalancerResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (api *LoadBalancerAPI) request(f func(*loadBalancerResponse) error) (*sacloud.LoadBalancer, error) {
|
||||
res := &loadBalancerResponse{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.LoadBalancer, nil
|
||||
}
|
||||
|
||||
func (api *LoadBalancerAPI) createRequest(value *sacloud.LoadBalancer) *loadBalancerResponse {
|
||||
return &loadBalancerResponse{LoadBalancer: value}
|
||||
}
|
||||
|
||||
//func (api *LoadBalancerAPI) New() *sacloud.LoadBalancer {
|
||||
// return sacloud.CreateNewLoadBalancer()
|
||||
//}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *LoadBalancerAPI) Create(value *sacloud.LoadBalancer) (*sacloud.LoadBalancer, error) {
|
||||
return api.request(func(res *loadBalancerResponse) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *LoadBalancerAPI) Read(id int64) (*sacloud.LoadBalancer, error) {
|
||||
return api.request(func(res *loadBalancerResponse) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *LoadBalancerAPI) Update(id int64, value *sacloud.LoadBalancer) (*sacloud.LoadBalancer, error) {
|
||||
return api.request(func(res *loadBalancerResponse) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *LoadBalancerAPI) Delete(id int64) (*sacloud.LoadBalancer, error) {
|
||||
return api.request(func(res *loadBalancerResponse) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Config 設定変更の反映
|
||||
func (api *LoadBalancerAPI) Config(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/config", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// IsUp 起動しているか判定
|
||||
func (api *LoadBalancerAPI) IsUp(id int64) (bool, error) {
|
||||
lb, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return lb.Instance.IsUp(), nil
|
||||
}
|
||||
|
||||
// IsDown ダウンしているか判定
|
||||
func (api *LoadBalancerAPI) IsDown(id int64) (bool, error) {
|
||||
lb, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return lb.Instance.IsDown(), nil
|
||||
}
|
||||
|
||||
// Boot 起動
|
||||
func (api *LoadBalancerAPI) Boot(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Shutdown シャットダウン(graceful)
|
||||
func (api *LoadBalancerAPI) Shutdown(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Stop シャットダウン(force)
|
||||
func (api *LoadBalancerAPI) Stop(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]bool{"Force": true})
|
||||
}
|
||||
|
||||
// RebootForce 再起動
|
||||
func (api *LoadBalancerAPI) RebootForce(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/reset", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// ResetForce リセット
|
||||
func (api *LoadBalancerAPI) ResetForce(id int64, recycleProcess bool) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/reset", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]bool{"RecycleProcess": recycleProcess})
|
||||
}
|
||||
|
||||
// SleepUntilUp 起動するまで待機
|
||||
func (api *LoadBalancerAPI) SleepUntilUp(id int64, timeout time.Duration) error {
|
||||
handler := waitingForUpFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// SleepUntilDown ダウンするまで待機
|
||||
func (api *LoadBalancerAPI) SleepUntilDown(id int64, timeout time.Duration) error {
|
||||
handler := waitingForDownFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// SleepWhileCopying コピー終了まで待機
|
||||
func (api *LoadBalancerAPI) SleepWhileCopying(id int64, timeout time.Duration, maxRetry int) error {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, maxRetry)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// AsyncSleepWhileCopying コピー終了まで待機(非同期)
|
||||
func (api *LoadBalancerAPI) AsyncSleepWhileCopying(id int64, timeout time.Duration, maxRetry int) (chan (interface{}), chan (interface{}), chan (error)) {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, maxRetry)
|
||||
return poll(handler, timeout)
|
||||
}
|
||||
|
||||
// Monitor アクティビティーモニター取得
|
||||
func (api *LoadBalancerAPI) Monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.applianceMonitorBy(id, "interface", 0, body)
|
||||
}
|
238
vendor/github.com/sacloud/libsacloud/api/load_balancer_gen.go
generated
vendored
Normal file
238
vendor/github.com/sacloud/libsacloud/api/load_balancer_gen.go
generated
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [LoadBalancerAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *LoadBalancerAPI) Reset() *LoadBalancerAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *LoadBalancerAPI) Offset(offset int) *LoadBalancerAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *LoadBalancerAPI) Limit(limit int) *LoadBalancerAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *LoadBalancerAPI) Include(key string) *LoadBalancerAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *LoadBalancerAPI) Exclude(key string) *LoadBalancerAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *LoadBalancerAPI) FilterBy(key string, value interface{}) *LoadBalancerAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *LoadBalancerAPI) FilterMultiBy(key string, value interface{}) *LoadBalancerAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *LoadBalancerAPI) WithNameLike(name string) *LoadBalancerAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *LoadBalancerAPI) WithTag(tag string) *LoadBalancerAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *LoadBalancerAPI) WithTags(tags []string) *LoadBalancerAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *LoadBalancerAPI) WithSizeGib(size int) *LoadBalancerAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *LoadBalancerAPI) WithSharedScope() *LoadBalancerAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *LoadBalancerAPI) WithUserScope() *LoadBalancerAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *LoadBalancerAPI) SortBy(key string, reverse bool) *LoadBalancerAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *LoadBalancerAPI) SortByName(reverse bool) *LoadBalancerAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *LoadBalancerAPI) SortBySize(reverse bool) *LoadBalancerAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *LoadBalancerAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *LoadBalancerAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *LoadBalancerAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *LoadBalancerAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *LoadBalancerAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *LoadBalancerAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *LoadBalancerAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *LoadBalancerAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *LoadBalancerAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *LoadBalancerAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *LoadBalancerAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *LoadBalancerAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *LoadBalancerAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *LoadBalancerAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *LoadBalancerAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *LoadBalancerAPI) SortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *LoadBalancerAPI) New() *sacloud.LoadBalancer {
|
||||
// return &sacloud.LoadBalancer{}
|
||||
// }
|
||||
|
||||
// func (api *LoadBalancerAPI) Create(value *sacloud.LoadBalancer) (*sacloud.LoadBalancer, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *LoadBalancerAPI) Read(id string) (*sacloud.LoadBalancer, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *LoadBalancerAPI) Update(id string, value *sacloud.LoadBalancer) (*sacloud.LoadBalancer, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *LoadBalancerAPI) Delete(id string) (*sacloud.LoadBalancer, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *LoadBalancerAPI) setStateValue(setFunc func(*sacloud.Request)) *LoadBalancerAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *LoadBalancerAPI) request(f func(*sacloud.Response) error) (*sacloud.LoadBalancer, error) {
|
||||
// res := &sacloud.Response{}
|
||||
// err := f(res)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return res.LoadBalancer, nil
|
||||
//}
|
||||
//
|
||||
//func (api *LoadBalancerAPI) createRequest(value *sacloud.LoadBalancer) *sacloud.Request {
|
||||
// req := &sacloud.Request{}
|
||||
// req.LoadBalancer = value
|
||||
// return req
|
||||
//}
|
414
vendor/github.com/sacloud/libsacloud/api/mobile_gateway.go
generated
vendored
Normal file
414
vendor/github.com/sacloud/libsacloud/api/mobile_gateway.go
generated
vendored
Normal file
@ -0,0 +1,414 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SearchMobileGatewayResponse モバイルゲートウェイ検索レスポンス
|
||||
type SearchMobileGatewayResponse struct {
|
||||
// Total 総件数
|
||||
Total int `json:",omitempty"`
|
||||
// From ページング開始位置
|
||||
From int `json:",omitempty"`
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// MobileGateways モバイルゲートウェイ リスト
|
||||
MobileGateways []sacloud.MobileGateway `json:"Appliances,omitempty"`
|
||||
}
|
||||
|
||||
// MobileGatewaySIMRequest SIM一覧取得リクエスト
|
||||
type MobileGatewaySIMRequest struct {
|
||||
From int `json:",omitempty"`
|
||||
Count int `json:",omitempty"`
|
||||
Sort []string `json:",omitempty"`
|
||||
Filter map[string]interface{} `json:",omitempty"`
|
||||
Exclude []string `json:",omitempty"`
|
||||
Include []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type mobileGatewayResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
*sacloud.MobileGateway `json:"Appliance,omitempty"`
|
||||
Success interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{}
|
||||
}
|
||||
|
||||
type mobileGatewaySIMResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
SIM []sacloud.SIMInfo `json:"sim,omitempty"`
|
||||
Success interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{}
|
||||
}
|
||||
|
||||
// MobileGatewayAPI モバイルゲートウェイAPI
|
||||
type MobileGatewayAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewMobileGatewayAPI モバイルゲートウェイAPI作成
|
||||
func NewMobileGatewayAPI(client *Client) *MobileGatewayAPI {
|
||||
return &MobileGatewayAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "appliance"
|
||||
},
|
||||
FuncBaseSearchCondition: func() *sacloud.Request {
|
||||
res := &sacloud.Request{}
|
||||
res.AddFilter("Class", "mobilegateway")
|
||||
return res
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Find 検索
|
||||
func (api *MobileGatewayAPI) Find() (*SearchMobileGatewayResponse, error) {
|
||||
data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res SearchMobileGatewayResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (api *MobileGatewayAPI) request(f func(*mobileGatewayResponse) error) (*sacloud.MobileGateway, error) {
|
||||
res := &mobileGatewayResponse{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.MobileGateway, nil
|
||||
}
|
||||
|
||||
func (api *MobileGatewayAPI) createRequest(value *sacloud.MobileGateway) *mobileGatewayResponse {
|
||||
return &mobileGatewayResponse{MobileGateway: value}
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *MobileGatewayAPI) Create(value *sacloud.MobileGateway) (*sacloud.MobileGateway, error) {
|
||||
return api.request(func(res *mobileGatewayResponse) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *MobileGatewayAPI) Read(id int64) (*sacloud.MobileGateway, error) {
|
||||
return api.request(func(res *mobileGatewayResponse) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *MobileGatewayAPI) Update(id int64, value *sacloud.MobileGateway) (*sacloud.MobileGateway, error) {
|
||||
return api.request(func(res *mobileGatewayResponse) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateSetting 設定更新
|
||||
func (api *MobileGatewayAPI) UpdateSetting(id int64, value *sacloud.MobileGateway) (*sacloud.MobileGateway, error) {
|
||||
req := &sacloud.MobileGateway{
|
||||
// Settings
|
||||
Settings: value.Settings,
|
||||
}
|
||||
return api.request(func(res *mobileGatewayResponse) error {
|
||||
return api.update(id, api.createRequest(req), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *MobileGatewayAPI) Delete(id int64) (*sacloud.MobileGateway, error) {
|
||||
return api.request(func(res *mobileGatewayResponse) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Config 設定変更の反映
|
||||
func (api *MobileGatewayAPI) Config(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/config", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// IsUp 起動しているか判定
|
||||
func (api *MobileGatewayAPI) IsUp(id int64) (bool, error) {
|
||||
lb, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return lb.Instance.IsUp(), nil
|
||||
}
|
||||
|
||||
// IsDown ダウンしているか判定
|
||||
func (api *MobileGatewayAPI) IsDown(id int64) (bool, error) {
|
||||
lb, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return lb.Instance.IsDown(), nil
|
||||
}
|
||||
|
||||
// Boot 起動
|
||||
func (api *MobileGatewayAPI) Boot(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Shutdown シャットダウン(graceful)
|
||||
func (api *MobileGatewayAPI) Shutdown(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Stop シャットダウン(force)
|
||||
func (api *MobileGatewayAPI) Stop(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]bool{"Force": true})
|
||||
}
|
||||
|
||||
// RebootForce 再起動
|
||||
func (api *MobileGatewayAPI) RebootForce(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/reset", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// ResetForce リセット
|
||||
func (api *MobileGatewayAPI) ResetForce(id int64, recycleProcess bool) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/reset", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]bool{"RecycleProcess": recycleProcess})
|
||||
}
|
||||
|
||||
// SleepUntilUp 起動するまで待機
|
||||
func (api *MobileGatewayAPI) SleepUntilUp(id int64, timeout time.Duration) error {
|
||||
handler := waitingForUpFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// SleepUntilDown ダウンするまで待機
|
||||
func (api *MobileGatewayAPI) SleepUntilDown(id int64, timeout time.Duration) error {
|
||||
handler := waitingForDownFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// SleepWhileCopying コピー終了まで待機
|
||||
func (api *MobileGatewayAPI) SleepWhileCopying(id int64, timeout time.Duration, maxRetry int) error {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, maxRetry)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// AsyncSleepWhileCopying コピー終了まで待機(非同期)
|
||||
func (api *MobileGatewayAPI) AsyncSleepWhileCopying(id int64, timeout time.Duration, maxRetry int) (chan (interface{}), chan (interface{}), chan (error)) {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, maxRetry)
|
||||
return poll(handler, timeout)
|
||||
}
|
||||
|
||||
// ConnectToSwitch 指定のインデックス位置のNICをスイッチへ接続
|
||||
func (api *MobileGatewayAPI) ConnectToSwitch(id int64, switchID int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/interface/%d/to/switch/%d", api.getResourceURL(), id, 1, switchID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// DisconnectFromSwitch 指定のインデックス位置のNICをスイッチから切断
|
||||
func (api *MobileGatewayAPI) DisconnectFromSwitch(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/interface/%d/to/switch", api.getResourceURL(), id, 1)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// GetDNS DNSサーバ設定 取得
|
||||
func (api *MobileGatewayAPI) GetDNS(id int64) (*sacloud.MobileGatewayResolver, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/mobilegateway/dnsresolver", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
data, err := api.client.newRequest(method, uri, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res sacloud.MobileGatewayResolver
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, err
|
||||
}
|
||||
|
||||
// SetDNS DNSサーバ設定
|
||||
func (api *MobileGatewayAPI) SetDNS(id int64, dns *sacloud.MobileGatewayResolver) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/mobilegateway/dnsresolver", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, dns)
|
||||
}
|
||||
|
||||
// GetSIMRoutes SIMルート 取得
|
||||
func (api *MobileGatewayAPI) GetSIMRoutes(id int64) ([]*sacloud.MobileGatewaySIMRoute, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/mobilegateway/simroutes", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
data, err := api.client.newRequest(method, uri, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res sacloud.MobileGatewaySIMRoutes
|
||||
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.SIMRoutes, err
|
||||
}
|
||||
|
||||
// SetSIMRoutes SIMルート 設定
|
||||
func (api *MobileGatewayAPI) SetSIMRoutes(id int64, simRoutes *sacloud.MobileGatewaySIMRoutes) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/mobilegateway/simroutes", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, simRoutes)
|
||||
}
|
||||
|
||||
// AddSIMRoute SIMルート 個別追加
|
||||
func (api *MobileGatewayAPI) AddSIMRoute(id int64, simID int64, prefix string) (bool, error) {
|
||||
|
||||
routes, err := api.GetSIMRoutes(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
param := &sacloud.MobileGatewaySIMRoutes{
|
||||
SIMRoutes: routes,
|
||||
}
|
||||
added := param.AddSIMRoute(simID, prefix)
|
||||
if !added {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return api.SetSIMRoutes(id, param)
|
||||
}
|
||||
|
||||
// DeleteSIMRoute SIMルート 個別削除
|
||||
func (api *MobileGatewayAPI) DeleteSIMRoute(id int64, simID int64, prefix string) (bool, error) {
|
||||
|
||||
routes, err := api.GetSIMRoutes(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
param := &sacloud.MobileGatewaySIMRoutes{
|
||||
SIMRoutes: routes,
|
||||
}
|
||||
deleted := param.DeleteSIMRoute(simID, prefix)
|
||||
if !deleted {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
_, err = api.SetSIMRoutes(id, param)
|
||||
return deleted, err
|
||||
}
|
||||
|
||||
// DeleteSIMRoutes SIMルート 全件削除
|
||||
func (api *MobileGatewayAPI) DeleteSIMRoutes(id int64) (bool, error) {
|
||||
return api.SetSIMRoutes(id, &sacloud.MobileGatewaySIMRoutes{
|
||||
SIMRoutes: []*sacloud.MobileGatewaySIMRoute{},
|
||||
})
|
||||
}
|
||||
|
||||
// ListSIM SIM一覧取得
|
||||
func (api *MobileGatewayAPI) ListSIM(id int64, req *MobileGatewaySIMRequest) ([]sacloud.SIMInfo, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/mobilegateway/sims", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
data, err := api.client.newRequest(method, uri, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res mobileGatewaySIMResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.SIM, nil
|
||||
}
|
||||
|
||||
// AddSIM SIM登録
|
||||
func (api *MobileGatewayAPI) AddSIM(id int64, simID int64) (bool, error) {
|
||||
var (
|
||||
method = "POST"
|
||||
uri = fmt.Sprintf("%s/%d/mobilegateway/sims", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]interface{}{
|
||||
"sim": map[string]interface{}{
|
||||
"resource_id": fmt.Sprintf("%d", simID),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteSIM SIM登録
|
||||
func (api *MobileGatewayAPI) DeleteSIM(id int64, simID int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/mobilegateway/sims/%d", api.getResourceURL(), id, simID)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Logs セッションログ取得(複数SIM)
|
||||
func (api *MobileGatewayAPI) Logs(id int64, body interface{}) ([]sacloud.SIMLog, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/mobilegateway/sessionlog", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
res := &simLogResponse{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Logs, nil
|
||||
}
|
238
vendor/github.com/sacloud/libsacloud/api/mobile_gateway_gen.go
generated
vendored
Normal file
238
vendor/github.com/sacloud/libsacloud/api/mobile_gateway_gen.go
generated
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [MobileGatewayAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *MobileGatewayAPI) Reset() *MobileGatewayAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *MobileGatewayAPI) Offset(offset int) *MobileGatewayAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *MobileGatewayAPI) Limit(limit int) *MobileGatewayAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *MobileGatewayAPI) Include(key string) *MobileGatewayAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *MobileGatewayAPI) Exclude(key string) *MobileGatewayAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *MobileGatewayAPI) FilterBy(key string, value interface{}) *MobileGatewayAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *MobileGatewayAPI) FilterMultiBy(key string, value interface{}) *MobileGatewayAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *MobileGatewayAPI) WithNameLike(name string) *MobileGatewayAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *MobileGatewayAPI) WithTag(tag string) *MobileGatewayAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *MobileGatewayAPI) WithTags(tags []string) *MobileGatewayAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *MobileGatewayAPI) WithSizeGib(size int) *MobileGatewayAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *MobileGatewayAPI) WithSharedScope() *MobileGatewayAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *MobileGatewayAPI) WithUserScope() *MobileGatewayAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *MobileGatewayAPI) SortBy(key string, reverse bool) *MobileGatewayAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *MobileGatewayAPI) SortByName(reverse bool) *MobileGatewayAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *MobileGatewayAPI) SortBySize(reverse bool) *MobileGatewayAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *MobileGatewayAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *MobileGatewayAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *MobileGatewayAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *MobileGatewayAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *MobileGatewayAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *MobileGatewayAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *MobileGatewayAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *MobileGatewayAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *MobileGatewayAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *MobileGatewayAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *MobileGatewayAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *MobileGatewayAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *MobileGatewayAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *MobileGatewayAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *MobileGatewayAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *MobileGatewayAPI) SortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *MobileGatewayAPI) New() *sacloud.MobileGateway {
|
||||
// return &sacloud.MobileGateway{}
|
||||
// }
|
||||
|
||||
// func (api *MobileGatewayAPI) Create(value *sacloud.MobileGateway) (*sacloud.MobileGateway, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *MobileGatewayAPI) Read(id string) (*sacloud.MobileGateway, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *MobileGatewayAPI) Update(id string, value *sacloud.MobileGateway) (*sacloud.MobileGateway, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *MobileGatewayAPI) Delete(id string) (*sacloud.MobileGateway, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *MobileGatewayAPI) setStateValue(setFunc func(*sacloud.Request)) *MobileGatewayAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *MobileGatewayAPI) request(f func(*sacloud.Response) error) (*sacloud.MobileGateway, error) {
|
||||
// res := &sacloud.Response{}
|
||||
// err := f(res)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return res.MobileGateway, nil
|
||||
//}
|
||||
//
|
||||
//func (api *MobileGatewayAPI) createRequest(value *sacloud.MobileGateway) *sacloud.Request {
|
||||
// req := &sacloud.Request{}
|
||||
// req.MobileGateway = value
|
||||
// return req
|
||||
//}
|
50
vendor/github.com/sacloud/libsacloud/api/newsfeed.go
generated
vendored
Normal file
50
vendor/github.com/sacloud/libsacloud/api/newsfeed.go
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
// NewsFeedAPI フィード(障害/メンテナンス情報)API
|
||||
type NewsFeedAPI struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// NewsFeedURL フィード取得URL
|
||||
var NewsFeedURL = "https://secure.sakura.ad.jp/rss/sakuranews/getfeeds.php?service=cloud&format=json"
|
||||
|
||||
// NewNewsFeedAPI フィード(障害/メンテナンス情報)API
|
||||
func NewNewsFeedAPI(client *Client) *NewsFeedAPI {
|
||||
return &NewsFeedAPI{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
// GetFeed フィード全件取得
|
||||
func (api *NewsFeedAPI) GetFeed() ([]sacloud.NewsFeed, error) {
|
||||
|
||||
var res = []sacloud.NewsFeed{}
|
||||
data, err := api.client.newRequest("GET", NewsFeedURL, nil)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// GetFeedByURL 指定のURLを持つフィードを取得
|
||||
func (api *NewsFeedAPI) GetFeedByURL(url string) (*sacloud.NewsFeed, error) {
|
||||
res, err := api.GetFeed()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, r := range res {
|
||||
if r.URL == url {
|
||||
return &r, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
234
vendor/github.com/sacloud/libsacloud/api/nfs.go
generated
vendored
Normal file
234
vendor/github.com/sacloud/libsacloud/api/nfs.go
generated
vendored
Normal file
@ -0,0 +1,234 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SearchNFSResponse NFS検索レスポンス
|
||||
type SearchNFSResponse struct {
|
||||
// Total 総件数
|
||||
Total int `json:",omitempty"`
|
||||
// From ページング開始位置
|
||||
From int `json:",omitempty"`
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// NFSs NFS リスト
|
||||
NFS []sacloud.NFS `json:"Appliances,omitempty"`
|
||||
}
|
||||
|
||||
type nfsRequest struct {
|
||||
NFS *sacloud.NFS `json:"Appliance,omitempty"`
|
||||
From int `json:",omitempty"`
|
||||
Count int `json:",omitempty"`
|
||||
Sort []string `json:",omitempty"`
|
||||
Filter map[string]interface{} `json:",omitempty"`
|
||||
Exclude []string `json:",omitempty"`
|
||||
Include []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type nfsResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
*sacloud.NFS `json:"Appliance,omitempty"`
|
||||
Success interface{} `json:",omitempty"` //HACK: さくらのAPI側仕様: 戻り値:Successがbool値へ変換できないためinterface{}
|
||||
}
|
||||
|
||||
// NFSAPI NFSAPI
|
||||
type NFSAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewNFSAPI NFSAPI作成
|
||||
func NewNFSAPI(client *Client) *NFSAPI {
|
||||
return &NFSAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "appliance"
|
||||
},
|
||||
FuncBaseSearchCondition: func() *sacloud.Request {
|
||||
res := &sacloud.Request{}
|
||||
res.AddFilter("Class", "nfs")
|
||||
return res
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Find 検索
|
||||
func (api *NFSAPI) Find() (*SearchNFSResponse, error) {
|
||||
data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res SearchNFSResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (api *NFSAPI) request(f func(*nfsResponse) error) (*sacloud.NFS, error) {
|
||||
res := &nfsResponse{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.NFS, nil
|
||||
}
|
||||
|
||||
func (api *NFSAPI) createRequest(value *sacloud.NFS) *nfsResponse {
|
||||
return &nfsResponse{NFS: value}
|
||||
}
|
||||
|
||||
//func (api *NFSAPI) New() *sacloud.NFS {
|
||||
// return sacloud.CreateNewNFS()
|
||||
//}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *NFSAPI) Create(value *sacloud.NFS) (*sacloud.NFS, error) {
|
||||
return api.request(func(res *nfsResponse) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *NFSAPI) Read(id int64) (*sacloud.NFS, error) {
|
||||
return api.request(func(res *nfsResponse) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *NFSAPI) Update(id int64, value *sacloud.NFS) (*sacloud.NFS, error) {
|
||||
return api.request(func(res *nfsResponse) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *NFSAPI) Delete(id int64) (*sacloud.NFS, error) {
|
||||
return api.request(func(res *nfsResponse) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Config 設定変更の反映
|
||||
func (api *NFSAPI) Config(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/config", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// IsUp 起動しているか判定
|
||||
func (api *NFSAPI) IsUp(id int64) (bool, error) {
|
||||
lb, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return lb.Instance.IsUp(), nil
|
||||
}
|
||||
|
||||
// IsDown ダウンしているか判定
|
||||
func (api *NFSAPI) IsDown(id int64) (bool, error) {
|
||||
lb, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return lb.Instance.IsDown(), nil
|
||||
}
|
||||
|
||||
// Boot 起動
|
||||
func (api *NFSAPI) Boot(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Shutdown シャットダウン(graceful)
|
||||
func (api *NFSAPI) Shutdown(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Stop シャットダウン(force)
|
||||
func (api *NFSAPI) Stop(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]bool{"Force": true})
|
||||
}
|
||||
|
||||
// RebootForce 再起動
|
||||
func (api *NFSAPI) RebootForce(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/reset", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// ResetForce リセット
|
||||
func (api *NFSAPI) ResetForce(id int64, recycleProcess bool) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/reset", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]bool{"RecycleProcess": recycleProcess})
|
||||
}
|
||||
|
||||
// SleepUntilUp 起動するまで待機
|
||||
func (api *NFSAPI) SleepUntilUp(id int64, timeout time.Duration) error {
|
||||
handler := waitingForUpFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// SleepUntilDown ダウンするまで待機
|
||||
func (api *NFSAPI) SleepUntilDown(id int64, timeout time.Duration) error {
|
||||
handler := waitingForDownFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// SleepWhileCopying コピー終了まで待機
|
||||
func (api *NFSAPI) SleepWhileCopying(id int64, timeout time.Duration, maxRetry int) error {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, maxRetry)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// AsyncSleepWhileCopying コピー終了まで待機(非同期)
|
||||
func (api *NFSAPI) AsyncSleepWhileCopying(id int64, timeout time.Duration, maxRetry int) (chan (interface{}), chan (interface{}), chan (error)) {
|
||||
handler := waitingForAvailableFunc(func() (hasAvailable, error) {
|
||||
return api.Read(id)
|
||||
}, maxRetry)
|
||||
return poll(handler, timeout)
|
||||
}
|
||||
|
||||
// MonitorNFS NFS固有項目アクティビティモニター取得
|
||||
func (api *NFSAPI) MonitorNFS(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.applianceMonitorBy(id, "nfs", 0, body)
|
||||
}
|
||||
|
||||
// MonitorInterface NICアクティビティーモニター取得
|
||||
func (api *NFSAPI) MonitorInterface(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.applianceMonitorBy(id, "interface", 0, body)
|
||||
}
|
238
vendor/github.com/sacloud/libsacloud/api/nfs_gen.go
generated
vendored
Normal file
238
vendor/github.com/sacloud/libsacloud/api/nfs_gen.go
generated
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [NFSAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *NFSAPI) Reset() *NFSAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *NFSAPI) Offset(offset int) *NFSAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *NFSAPI) Limit(limit int) *NFSAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *NFSAPI) Include(key string) *NFSAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *NFSAPI) Exclude(key string) *NFSAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *NFSAPI) FilterBy(key string, value interface{}) *NFSAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *NFSAPI) FilterMultiBy(key string, value interface{}) *NFSAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *NFSAPI) WithNameLike(name string) *NFSAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *NFSAPI) WithTag(tag string) *NFSAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *NFSAPI) WithTags(tags []string) *NFSAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *NFSAPI) WithSizeGib(size int) *NFSAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *NFSAPI) WithSharedScope() *NFSAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *NFSAPI) WithUserScope() *NFSAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *NFSAPI) SortBy(key string, reverse bool) *NFSAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *NFSAPI) SortByName(reverse bool) *NFSAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *NFSAPI) SortBySize(reverse bool) *NFSAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *NFSAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *NFSAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *NFSAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *NFSAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *NFSAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *NFSAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *NFSAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *NFSAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *NFSAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *NFSAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *NFSAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *NFSAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *NFSAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *NFSAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *NFSAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *NFSAPI) SortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *NFSAPI) New() *sacloud.NFS {
|
||||
// return &sacloud.NFS{}
|
||||
// }
|
||||
|
||||
// func (api *NFSAPI) Create(value *sacloud.NFS) (*sacloud.NFS, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *NFSAPI) Read(id string) (*sacloud.NFS, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *NFSAPI) Update(id string, value *sacloud.NFS) (*sacloud.NFS, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *NFSAPI) Delete(id string) (*sacloud.NFS, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *NFSAPI) setStateValue(setFunc func(*sacloud.Request)) *NFSAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *NFSAPI) request(f func(*sacloud.Response) error) (*sacloud.NFS, error) {
|
||||
// res := &sacloud.Response{}
|
||||
// err := f(res)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return res.NFS, nil
|
||||
//}
|
||||
//
|
||||
//func (api *NFSAPI) createRequest(value *sacloud.NFS) *sacloud.Request {
|
||||
// req := &sacloud.Request{}
|
||||
// req.NFS = value
|
||||
// return req
|
||||
//}
|
18
vendor/github.com/sacloud/libsacloud/api/note.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/note.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// NoteAPI スタートアップスクリプトAPI
|
||||
type NoteAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewNoteAPI スタートアップスクリプトAPI作成
|
||||
func NewNoteAPI(client *Client) *NoteAPI {
|
||||
return &NoteAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "note"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
247
vendor/github.com/sacloud/libsacloud/api/note_gen.go
generated
vendored
Normal file
247
vendor/github.com/sacloud/libsacloud/api/note_gen.go
generated
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [NoteAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *NoteAPI) Reset() *NoteAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *NoteAPI) Offset(offset int) *NoteAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *NoteAPI) Limit(limit int) *NoteAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *NoteAPI) Include(key string) *NoteAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *NoteAPI) Exclude(key string) *NoteAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *NoteAPI) FilterBy(key string, value interface{}) *NoteAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *NoteAPI) FilterMultiBy(key string, value interface{}) *NoteAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *NoteAPI) WithNameLike(name string) *NoteAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *NoteAPI) WithTag(tag string) *NoteAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *NoteAPI) WithTags(tags []string) *NoteAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *NoteAPI) WithSizeGib(size int) *NoteAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// WithSharedScope 公開スコープ条件
|
||||
func (api *NoteAPI) WithSharedScope() *NoteAPI {
|
||||
api.FilterBy("Scope", "shared")
|
||||
return api
|
||||
}
|
||||
|
||||
// WithUserScope ユーザースコープ条件
|
||||
func (api *NoteAPI) WithUserScope() *NoteAPI {
|
||||
api.FilterBy("Scope", "user")
|
||||
return api
|
||||
}
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *NoteAPI) SortBy(key string, reverse bool) *NoteAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *NoteAPI) SortByName(reverse bool) *NoteAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *NoteAPI) SortBySize(reverse bool) *NoteAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *NoteAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *NoteAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *NoteAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *NoteAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *NoteAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *NoteAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *NoteAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *NoteAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *NoteAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *NoteAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *NoteAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// SetSharedScope 公開スコープ条件
|
||||
func (api *NoteAPI) SetSharedScope() {
|
||||
api.FilterBy("Scope", "shared")
|
||||
}
|
||||
|
||||
// SetUserScope ユーザースコープ条件
|
||||
func (api *NoteAPI) SetUserScope() {
|
||||
api.FilterBy("Scope", "user")
|
||||
}
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *NoteAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *NoteAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *NoteAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *NoteAPI) New() *sacloud.Note {
|
||||
return &sacloud.Note{}
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *NoteAPI) Create(value *sacloud.Note) (*sacloud.Note, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *NoteAPI) Read(id int64) (*sacloud.Note, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *NoteAPI) Update(id int64, value *sacloud.Note) (*sacloud.Note, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *NoteAPI) Delete(id int64) (*sacloud.Note, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *NoteAPI) setStateValue(setFunc func(*sacloud.Request)) *NoteAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *NoteAPI) request(f func(*sacloud.Response) error) (*sacloud.Note, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Note, nil
|
||||
}
|
||||
|
||||
func (api *NoteAPI) createRequest(value *sacloud.Note) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.Note = value
|
||||
return req
|
||||
}
|
18
vendor/github.com/sacloud/libsacloud/api/packet_filter.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/packet_filter.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// PacketFilterAPI パケットフィルターAPI
|
||||
type PacketFilterAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewPacketFilterAPI パケットフィルターAPI作成
|
||||
func NewPacketFilterAPI(client *Client) *PacketFilterAPI {
|
||||
return &PacketFilterAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "packetfilter"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
243
vendor/github.com/sacloud/libsacloud/api/packet_filter_gen.go
generated
vendored
Normal file
243
vendor/github.com/sacloud/libsacloud/api/packet_filter_gen.go
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [PacketFilterAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *PacketFilterAPI) Reset() *PacketFilterAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *PacketFilterAPI) Offset(offset int) *PacketFilterAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *PacketFilterAPI) Limit(limit int) *PacketFilterAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *PacketFilterAPI) Include(key string) *PacketFilterAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *PacketFilterAPI) Exclude(key string) *PacketFilterAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *PacketFilterAPI) FilterBy(key string, value interface{}) *PacketFilterAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *PacketFilterAPI) FilterMultiBy(key string, value interface{}) *PacketFilterAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *PacketFilterAPI) WithNameLike(name string) *PacketFilterAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *PacketFilterAPI) WithTag(tag string) *PacketFilterAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *PacketFilterAPI) WithTags(tags []string) *PacketFilterAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *PacketFilterAPI) WithSizeGib(size int) *PacketFilterAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *PacketFilterAPI) WithSharedScope() *PacketFilterAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *PacketFilterAPI) WithUserScope() *PacketFilterAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *PacketFilterAPI) SortBy(key string, reverse bool) *PacketFilterAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *PacketFilterAPI) SortByName(reverse bool) *PacketFilterAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *PacketFilterAPI) SortBySize(reverse bool) *PacketFilterAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *PacketFilterAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *PacketFilterAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *PacketFilterAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *PacketFilterAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *PacketFilterAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *PacketFilterAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *PacketFilterAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *PacketFilterAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *PacketFilterAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *PacketFilterAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *PacketFilterAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *PacketFilterAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *PacketFilterAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *PacketFilterAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *PacketFilterAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *PacketFilterAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *PacketFilterAPI) New() *sacloud.PacketFilter {
|
||||
return sacloud.CreateNewPacketFilter()
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *PacketFilterAPI) Create(value *sacloud.PacketFilter) (*sacloud.PacketFilter, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *PacketFilterAPI) Read(id int64) (*sacloud.PacketFilter, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *PacketFilterAPI) Update(id int64, value *sacloud.PacketFilter) (*sacloud.PacketFilter, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *PacketFilterAPI) Delete(id int64) (*sacloud.PacketFilter, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *PacketFilterAPI) setStateValue(setFunc func(*sacloud.Request)) *PacketFilterAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *PacketFilterAPI) request(f func(*sacloud.Response) error) (*sacloud.PacketFilter, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.PacketFilter, nil
|
||||
}
|
||||
|
||||
func (api *PacketFilterAPI) createRequest(value *sacloud.PacketFilter) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.PacketFilter = value
|
||||
return req
|
||||
}
|
156
vendor/github.com/sacloud/libsacloud/api/polling.go
generated
vendored
Normal file
156
vendor/github.com/sacloud/libsacloud/api/polling.go
generated
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type pollingHandler func() (exit bool, state interface{}, err error)
|
||||
|
||||
func poll(handler pollingHandler, timeout time.Duration) (chan (interface{}), chan (interface{}), chan (error)) {
|
||||
|
||||
compChan := make(chan interface{})
|
||||
progChan := make(chan interface{})
|
||||
errChan := make(chan error)
|
||||
|
||||
tick := time.Tick(5 * time.Second)
|
||||
bomb := time.After(timeout)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-tick:
|
||||
exit, state, err := handler()
|
||||
if err != nil {
|
||||
errChan <- fmt.Errorf("Failed: poll: %s", err)
|
||||
return
|
||||
}
|
||||
if state != nil {
|
||||
progChan <- state
|
||||
if exit {
|
||||
compChan <- state
|
||||
return
|
||||
}
|
||||
}
|
||||
case <-bomb:
|
||||
errChan <- fmt.Errorf("Timeout")
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return compChan, progChan, errChan
|
||||
}
|
||||
|
||||
func blockingPoll(handler pollingHandler, timeout time.Duration) error {
|
||||
c, p, e := poll(handler, timeout)
|
||||
for {
|
||||
select {
|
||||
case <-c:
|
||||
return nil
|
||||
case <-p:
|
||||
// noop
|
||||
case err := <-e:
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type hasAvailable interface {
|
||||
IsAvailable() bool
|
||||
}
|
||||
type hasFailed interface {
|
||||
IsFailed() bool
|
||||
}
|
||||
|
||||
func waitingForAvailableFunc(readFunc func() (hasAvailable, error), maxRetry int) func() (bool, interface{}, error) {
|
||||
counter := 0
|
||||
return func() (bool, interface{}, error) {
|
||||
counter++
|
||||
v, err := readFunc()
|
||||
if err != nil {
|
||||
if maxRetry > 0 && counter < maxRetry {
|
||||
return false, nil, nil
|
||||
}
|
||||
return false, nil, err
|
||||
}
|
||||
if v == nil {
|
||||
return false, nil, fmt.Errorf("readFunc returns nil")
|
||||
}
|
||||
|
||||
if v.IsAvailable() {
|
||||
return true, v, nil
|
||||
}
|
||||
if f, ok := v.(hasFailed); ok && f.IsFailed() {
|
||||
return false, v, fmt.Errorf("InstanceState is failed: %#v", v)
|
||||
}
|
||||
|
||||
return false, v, nil
|
||||
}
|
||||
}
|
||||
|
||||
type hasUpDown interface {
|
||||
IsUp() bool
|
||||
IsDown() bool
|
||||
}
|
||||
|
||||
func waitingForUpFunc(readFunc func() (hasUpDown, error), maxRetry int) func() (bool, interface{}, error) {
|
||||
counter := 0
|
||||
return func() (bool, interface{}, error) {
|
||||
counter++
|
||||
v, err := readFunc()
|
||||
if err != nil {
|
||||
if maxRetry > 0 && counter < maxRetry {
|
||||
return false, nil, nil
|
||||
}
|
||||
return false, nil, err
|
||||
}
|
||||
if v == nil {
|
||||
return false, nil, fmt.Errorf("readFunc returns nil")
|
||||
}
|
||||
|
||||
if v.IsUp() {
|
||||
return true, v, nil
|
||||
}
|
||||
return false, v, nil
|
||||
}
|
||||
}
|
||||
|
||||
func waitingForDownFunc(readFunc func() (hasUpDown, error), maxRetry int) func() (bool, interface{}, error) {
|
||||
counter := 0
|
||||
return func() (bool, interface{}, error) {
|
||||
counter++
|
||||
v, err := readFunc()
|
||||
if err != nil {
|
||||
if maxRetry > 0 && counter < maxRetry {
|
||||
return false, nil, nil
|
||||
}
|
||||
return false, nil, err
|
||||
}
|
||||
if v == nil {
|
||||
return false, nil, fmt.Errorf("readFunc returns nil")
|
||||
}
|
||||
|
||||
if v.IsDown() {
|
||||
return true, v, nil
|
||||
}
|
||||
return false, v, nil
|
||||
}
|
||||
}
|
||||
|
||||
func waitingForReadFunc(readFunc func() (interface{}, error), maxRetry int) func() (bool, interface{}, error) {
|
||||
counter := 0
|
||||
return func() (bool, interface{}, error) {
|
||||
counter++
|
||||
v, err := readFunc()
|
||||
if err != nil {
|
||||
if maxRetry > 0 && counter < maxRetry {
|
||||
return false, nil, nil
|
||||
}
|
||||
return false, nil, err
|
||||
}
|
||||
if v != nil {
|
||||
return true, v, nil
|
||||
}
|
||||
return false, v, nil
|
||||
}
|
||||
}
|
18
vendor/github.com/sacloud/libsacloud/api/private_host.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/private_host.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// PrivateHostAPI 専有ホストAPI
|
||||
type PrivateHostAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewPrivateHostAPI 専有ホストAPI作成
|
||||
func NewPrivateHostAPI(client *Client) *PrivateHostAPI {
|
||||
return &PrivateHostAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "privatehost"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
243
vendor/github.com/sacloud/libsacloud/api/private_host_gen.go
generated
vendored
Normal file
243
vendor/github.com/sacloud/libsacloud/api/private_host_gen.go
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [PrivateHostAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件リセット
|
||||
func (api *PrivateHostAPI) Reset() *PrivateHostAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *PrivateHostAPI) Offset(offset int) *PrivateHostAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *PrivateHostAPI) Limit(limit int) *PrivateHostAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *PrivateHostAPI) Include(key string) *PrivateHostAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *PrivateHostAPI) Exclude(key string) *PrivateHostAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *PrivateHostAPI) FilterBy(key string, value interface{}) *PrivateHostAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *PrivateHostAPI) FilterMultiBy(key string, value interface{}) *PrivateHostAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *PrivateHostAPI) WithNameLike(name string) *PrivateHostAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *PrivateHostAPI) WithTag(tag string) *PrivateHostAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *PrivateHostAPI) WithTags(tags []string) *PrivateHostAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *PrivateHostAPI) WithSizeGib(size int) *PrivateHostAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *PrivateHostAPI) WithSharedScope() *PrivateHostAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *PrivateHostAPI) WithUserScope() *PrivateHostAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *PrivateHostAPI) SortBy(key string, reverse bool) *PrivateHostAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *PrivateHostAPI) SortByName(reverse bool) *PrivateHostAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *PrivateHostAPI) SortBySize(reverse bool) *PrivateHostAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件リセット
|
||||
func (api *PrivateHostAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *PrivateHostAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *PrivateHostAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *PrivateHostAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *PrivateHostAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *PrivateHostAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *PrivateHostAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *PrivateHostAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *PrivateHostAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *PrivateHostAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *PrivateHostAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *PrivateHostAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *PrivateHostAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *PrivateHostAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *PrivateHostAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *PrivateHostAPI) SortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *PrivateHostAPI) New() *sacloud.PrivateHost {
|
||||
return &sacloud.PrivateHost{}
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *PrivateHostAPI) Create(value *sacloud.PrivateHost) (*sacloud.PrivateHost, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *PrivateHostAPI) Read(id int64) (*sacloud.PrivateHost, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *PrivateHostAPI) Update(id int64, value *sacloud.PrivateHost) (*sacloud.PrivateHost, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *PrivateHostAPI) Delete(id int64) (*sacloud.PrivateHost, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *PrivateHostAPI) setStateValue(setFunc func(*sacloud.Request)) *PrivateHostAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *PrivateHostAPI) request(f func(*sacloud.Response) error) (*sacloud.PrivateHost, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.PrivateHost, nil
|
||||
}
|
||||
|
||||
func (api *PrivateHostAPI) createRequest(value *sacloud.PrivateHost) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.PrivateHost = value
|
||||
return req
|
||||
}
|
18
vendor/github.com/sacloud/libsacloud/api/product_disk.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/product_disk.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// ProductDiskAPI ディスクプランAPI
|
||||
type ProductDiskAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewProductDiskAPI ディスクプランAPI作成
|
||||
func NewProductDiskAPI(client *Client) *ProductDiskAPI {
|
||||
return &ProductDiskAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "product/disk"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
239
vendor/github.com/sacloud/libsacloud/api/product_disk_gen.go
generated
vendored
Normal file
239
vendor/github.com/sacloud/libsacloud/api/product_disk_gen.go
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [ProductDiskAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *ProductDiskAPI) Reset() *ProductDiskAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *ProductDiskAPI) Offset(offset int) *ProductDiskAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *ProductDiskAPI) Limit(limit int) *ProductDiskAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *ProductDiskAPI) Include(key string) *ProductDiskAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *ProductDiskAPI) Exclude(key string) *ProductDiskAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *ProductDiskAPI) FilterBy(key string, value interface{}) *ProductDiskAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ProductDiskAPI) FilterMultiBy(key string, value interface{}) *ProductDiskAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *ProductDiskAPI) WithNameLike(name string) *ProductDiskAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *ProductDiskAPI) WithTag(tag string) *ProductDiskAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *ProductDiskAPI) WithTags(tags []string) *ProductDiskAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ProductDiskAPI) WithSizeGib(size int) *ProductDiskAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ProductDiskAPI) WithSharedScope() *ProductDiskAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ProductDiskAPI) WithUserScope() *ProductDiskAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *ProductDiskAPI) SortBy(key string, reverse bool) *ProductDiskAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *ProductDiskAPI) SortByName(reverse bool) *ProductDiskAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *ProductDiskAPI) SortBySize(reverse bool) *ProductDiskAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *ProductDiskAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *ProductDiskAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *ProductDiskAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *ProductDiskAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *ProductDiskAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *ProductDiskAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ProductDiskAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *ProductDiskAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *ProductDiskAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *ProductDiskAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ProductDiskAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *ProductDiskAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *ProductDiskAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *ProductDiskAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *ProductDiskAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *ProductDiskAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *ProductDiskAPI) New() *sacloud.ProductDisk {
|
||||
// return &sacloud.ProductDisk{}
|
||||
// }
|
||||
|
||||
// func (api *ProductDiskAPI) Create(value *sacloud.ProductDisk) (*sacloud.ProductDisk, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// Read 読み取り
|
||||
func (api *ProductDiskAPI) Read(id int64) (*sacloud.ProductDisk, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// func (api *ProductDiskAPI) Update(id int64, value *sacloud.ProductDisk) (*sacloud.ProductDisk, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *ProductDiskAPI) Delete(id int64) (*sacloud.ProductDisk, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *ProductDiskAPI) setStateValue(setFunc func(*sacloud.Request)) *ProductDiskAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *ProductDiskAPI) request(f func(*sacloud.Response) error) (*sacloud.ProductDisk, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.DiskPlan, nil
|
||||
}
|
||||
|
||||
func (api *ProductDiskAPI) createRequest(value *sacloud.ProductDisk) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.DiskPlan = value
|
||||
return req
|
||||
}
|
18
vendor/github.com/sacloud/libsacloud/api/product_internet.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/product_internet.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// ProductInternetAPI ルータープランAPI
|
||||
type ProductInternetAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewProductInternetAPI ルータープランAPI作成
|
||||
func NewProductInternetAPI(client *Client) *ProductInternetAPI {
|
||||
return &ProductInternetAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "product/internet"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
239
vendor/github.com/sacloud/libsacloud/api/product_internet_gen.go
generated
vendored
Normal file
239
vendor/github.com/sacloud/libsacloud/api/product_internet_gen.go
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [ProductInternetAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *ProductInternetAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *ProductInternetAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *ProductInternetAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *ProductInternetAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *ProductInternetAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *ProductInternetAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ProductInternetAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *ProductInternetAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *ProductInternetAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *ProductInternetAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ProductInternetAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *ProductInternetAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *ProductInternetAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *ProductInternetAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *ProductInternetAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *ProductInternetAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *ProductInternetAPI) Reset() *ProductInternetAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *ProductInternetAPI) Offset(offset int) *ProductInternetAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *ProductInternetAPI) Limit(limit int) *ProductInternetAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *ProductInternetAPI) Include(key string) *ProductInternetAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *ProductInternetAPI) Exclude(key string) *ProductInternetAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *ProductInternetAPI) FilterBy(key string, value interface{}) *ProductInternetAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ProductInternetAPI) FilterMultiBy(key string, value interface{}) *ProductInternetAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *ProductInternetAPI) WithNameLike(name string) *ProductInternetAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *ProductInternetAPI) WithTag(tag string) *ProductInternetAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *ProductInternetAPI) WithTags(tags []string) *ProductInternetAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ProductInternetAPI) WithSizeGib(size int) *ProductInternetAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ProductInternetAPI) WithSharedScope() *ProductInternetAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ProductInternetAPI) WithUserScope() *ProductInternetAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *ProductInternetAPI) SortBy(key string, reverse bool) *ProductInternetAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *ProductInternetAPI) SortByName(reverse bool) *ProductInternetAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *ProductInternetAPI) SortBySize(reverse bool) *ProductInternetAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
//func (api *ProductInternetAPI) New() *sacloud.ProductInternet {
|
||||
// return &sacloud.ProductInternet{}
|
||||
//}
|
||||
|
||||
// func (api *ProductInternetAPI) Create(value *sacloud.ProductInternet) (*sacloud.ProductInternet, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// Read 読み取り
|
||||
func (api *ProductInternetAPI) Read(id int64) (*sacloud.ProductInternet, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// func (api *ProductInternetAPI) Update(id int64, value *sacloud.ProductInternet) (*sacloud.ProductInternet, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *ProductInternetAPI) Delete(id int64) (*sacloud.ProductInternet, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *ProductInternetAPI) setStateValue(setFunc func(*sacloud.Request)) *ProductInternetAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *ProductInternetAPI) request(f func(*sacloud.Response) error) (*sacloud.ProductInternet, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.InternetPlan, nil
|
||||
}
|
||||
|
||||
func (api *ProductInternetAPI) createRequest(value *sacloud.ProductInternet) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.InternetPlan = value
|
||||
return req
|
||||
}
|
18
vendor/github.com/sacloud/libsacloud/api/product_license.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/product_license.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// ProductLicenseAPI ライセンスプランAPI
|
||||
type ProductLicenseAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewProductLicenseAPI ライセンスプランAPI作成
|
||||
func NewProductLicenseAPI(client *Client) *ProductLicenseAPI {
|
||||
return &ProductLicenseAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "product/license"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
235
vendor/github.com/sacloud/libsacloud/api/product_license_gen.go
generated
vendored
Normal file
235
vendor/github.com/sacloud/libsacloud/api/product_license_gen.go
generated
vendored
Normal file
@ -0,0 +1,235 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [ProductLicenseAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *ProductLicenseAPI) Reset() *ProductLicenseAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *ProductLicenseAPI) Offset(offset int) *ProductLicenseAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *ProductLicenseAPI) Limit(limit int) *ProductLicenseAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *ProductLicenseAPI) Include(key string) *ProductLicenseAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *ProductLicenseAPI) Exclude(key string) *ProductLicenseAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *ProductLicenseAPI) FilterBy(key string, value interface{}) *ProductLicenseAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ProductLicenseAPI) FilterMultiBy(key string, value interface{}) *ProductLicenseAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *ProductLicenseAPI) WithNameLike(name string) *ProductLicenseAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *ProductLicenseAPI) WithTag(tag string) *ProductLicenseAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *ProductLicenseAPI) WithTags(tags []string) *ProductLicenseAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ProductLicenseAPI) WithSizeGib(size int) *ProductLicenseAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ProductLicenseAPI) WithSharedScope() *ProductLicenseAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ProductLicenseAPI) WithUserScope() *ProductLicenseAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *ProductLicenseAPI) SortBy(key string, reverse bool) *ProductLicenseAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *ProductLicenseAPI) SortByName(reverse bool) *ProductLicenseAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *ProductLicenseAPI) SortBySize(reverse bool) *ProductLicenseAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *ProductLicenseAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *ProductLicenseAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *ProductLicenseAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *ProductLicenseAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *ProductLicenseAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *ProductLicenseAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ProductLicenseAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *ProductLicenseAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *ProductLicenseAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *ProductLicenseAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ProductLicenseAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *ProductLicenseAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *ProductLicenseAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *ProductLicenseAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *ProductLicenseAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *ProductLicenseAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *ProductLicenseAPI) Create(value *sacloud.ProductLicense) (*sacloud.ProductLicense, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// Read 読み取り
|
||||
func (api *ProductLicenseAPI) Read(id int64) (*sacloud.ProductLicense, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// func (api *ProductLicenseAPI) Update(id int64, value *sacloud.ProductLicense) (*sacloud.ProductLicense, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *ProductLicenseAPI) Delete(id int64) (*sacloud.ProductLicense, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *ProductLicenseAPI) setStateValue(setFunc func(*sacloud.Request)) *ProductLicenseAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *ProductLicenseAPI) request(f func(*sacloud.Response) error) (*sacloud.ProductLicense, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.LicenseInfo, nil
|
||||
}
|
||||
|
||||
func (api *ProductLicenseAPI) createRequest(value *sacloud.ProductLicense) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.LicenseInfo = value
|
||||
return req
|
||||
}
|
19
vendor/github.com/sacloud/libsacloud/api/product_private_host.go
generated
vendored
Normal file
19
vendor/github.com/sacloud/libsacloud/api/product_private_host.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
package api
|
||||
|
||||
// ProductPrivateHostAPI 専有ホストプランAPI
|
||||
type ProductPrivateHostAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewProductPrivateHostAPI 専有ホストプランAPI作成
|
||||
func NewProductPrivateHostAPI(client *Client) *ProductPrivateHostAPI {
|
||||
return &ProductPrivateHostAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
// FuncGetResourceURL
|
||||
FuncGetResourceURL: func() string {
|
||||
return "product/privatehost"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
239
vendor/github.com/sacloud/libsacloud/api/product_private_host_gen.go
generated
vendored
Normal file
239
vendor/github.com/sacloud/libsacloud/api/product_private_host_gen.go
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [ProductPrivateHostAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *ProductPrivateHostAPI) Reset() *ProductPrivateHostAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *ProductPrivateHostAPI) Offset(offset int) *ProductPrivateHostAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *ProductPrivateHostAPI) Limit(limit int) *ProductPrivateHostAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *ProductPrivateHostAPI) Include(key string) *ProductPrivateHostAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *ProductPrivateHostAPI) Exclude(key string) *ProductPrivateHostAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *ProductPrivateHostAPI) FilterBy(key string, value interface{}) *ProductPrivateHostAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ProductPrivateHostAPI) FilterMultiBy(key string, value interface{}) *ProductPrivateHostAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *ProductPrivateHostAPI) WithNameLike(name string) *ProductPrivateHostAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *ProductPrivateHostAPI) WithTag(tag string) *ProductPrivateHostAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *ProductPrivateHostAPI) WithTags(tags []string) *ProductPrivateHostAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ProductPrivateHostAPI) WithSizeGib(size int) *ProductPrivateHostAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ProductPrivateHostAPI) WithSharedScope() *ProductPrivateHostAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ProductPrivateHostAPI) WithUserScope() *ProductPrivateHostAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *ProductPrivateHostAPI) SortBy(key string, reverse bool) *ProductPrivateHostAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *ProductPrivateHostAPI) SortByName(reverse bool) *ProductPrivateHostAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *ProductPrivateHostAPI) SortBySize(reverse bool) *ProductPrivateHostAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *ProductPrivateHostAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *ProductPrivateHostAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *ProductPrivateHostAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *ProductPrivateHostAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *ProductPrivateHostAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *ProductPrivateHostAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ProductPrivateHostAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *ProductPrivateHostAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *ProductPrivateHostAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *ProductPrivateHostAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ProductPrivateHostAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *ProductPrivateHostAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *ProductPrivateHostAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *ProductPrivateHostAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *ProductPrivateHostAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *ProductPrivateHostAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
//func (api *ProductPrivateHostAPI) New() *sacloud.ProductPrivateHost {
|
||||
// return &sacloud.ProductPrivateHost{}
|
||||
//}
|
||||
|
||||
// func (api *ProductPrivateHostAPI) Create(value *sacloud.ProductPrivateHost) (*sacloud.ProductPrivateHost, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// Read 読み取り
|
||||
func (api *ProductPrivateHostAPI) Read(id int64) (*sacloud.ProductPrivateHost, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// func (api *ProductPrivateHostAPI) Update(id int64, value *sacloud.ProductPrivateHost) (*sacloud.ProductPrivateHost, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *ProductPrivateHostAPI) Delete(id int64) (*sacloud.ProductPrivateHost, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *ProductPrivateHostAPI) setStateValue(setFunc func(*sacloud.Request)) *ProductPrivateHostAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *ProductPrivateHostAPI) request(f func(*sacloud.Response) error) (*sacloud.ProductPrivateHost, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.PrivateHostPlan, nil
|
||||
}
|
||||
|
||||
func (api *ProductPrivateHostAPI) createRequest(value *sacloud.ProductPrivateHost) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.PrivateHostPlan = value
|
||||
return req
|
||||
}
|
71
vendor/github.com/sacloud/libsacloud/api/product_server.go
generated
vendored
Normal file
71
vendor/github.com/sacloud/libsacloud/api/product_server.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// ProductServerAPI サーバープランAPI
|
||||
type ProductServerAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewProductServerAPI サーバープランAPI作成
|
||||
func NewProductServerAPI(client *Client) *ProductServerAPI {
|
||||
return &ProductServerAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
// FuncGetResourceURL
|
||||
FuncGetResourceURL: func() string {
|
||||
return "product/server"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (api *ProductServerAPI) getPlanIDBySpec(core int, memGB int) (int64, error) {
|
||||
//assert args
|
||||
if core <= 0 {
|
||||
return -1, fmt.Errorf("Invalid Parameter: CPU Core")
|
||||
}
|
||||
if memGB <= 0 {
|
||||
return -1, fmt.Errorf("Invalid Parameter: Memory Size(GB)")
|
||||
}
|
||||
|
||||
return strconv.ParseInt(fmt.Sprintf("%d%03d", memGB, core), 10, 64)
|
||||
}
|
||||
|
||||
// IsValidPlan 指定のコア数/メモリサイズのプランが存在し、有効であるか判定
|
||||
func (api *ProductServerAPI) IsValidPlan(core int, memGB int) (bool, error) {
|
||||
|
||||
planID, err := api.getPlanIDBySpec(core, memGB)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
productServer, err := api.Read(planID)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if productServer != nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("Server Plan[%d] Not Found", planID)
|
||||
|
||||
}
|
||||
|
||||
// GetBySpec 指定のコア数/メモリサイズのサーバープランを取得
|
||||
func (api *ProductServerAPI) GetBySpec(core int, memGB int) (*sacloud.ProductServer, error) {
|
||||
planID, err := api.getPlanIDBySpec(core, memGB)
|
||||
|
||||
productServer, err := api.Read(planID)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return productServer, nil
|
||||
}
|
239
vendor/github.com/sacloud/libsacloud/api/product_server_gen.go
generated
vendored
Normal file
239
vendor/github.com/sacloud/libsacloud/api/product_server_gen.go
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [ProductServerAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *ProductServerAPI) Reset() *ProductServerAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *ProductServerAPI) Offset(offset int) *ProductServerAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *ProductServerAPI) Limit(limit int) *ProductServerAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *ProductServerAPI) Include(key string) *ProductServerAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *ProductServerAPI) Exclude(key string) *ProductServerAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *ProductServerAPI) FilterBy(key string, value interface{}) *ProductServerAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ProductServerAPI) FilterMultiBy(key string, value interface{}) *ProductServerAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *ProductServerAPI) WithNameLike(name string) *ProductServerAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *ProductServerAPI) WithTag(tag string) *ProductServerAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *ProductServerAPI) WithTags(tags []string) *ProductServerAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ProductServerAPI) WithSizeGib(size int) *ProductServerAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ProductServerAPI) WithSharedScope() *ProductServerAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ProductServerAPI) WithUserScope() *ProductServerAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *ProductServerAPI) SortBy(key string, reverse bool) *ProductServerAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *ProductServerAPI) SortByName(reverse bool) *ProductServerAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *ProductServerAPI) SortBySize(reverse bool) *ProductServerAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *ProductServerAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *ProductServerAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *ProductServerAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *ProductServerAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *ProductServerAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *ProductServerAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ProductServerAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *ProductServerAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *ProductServerAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *ProductServerAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ProductServerAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *ProductServerAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *ProductServerAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *ProductServerAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *ProductServerAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *ProductServerAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
//func (api *ProductServerAPI) New() *sacloud.ProductServer {
|
||||
// return &sacloud.ProductServer{}
|
||||
//}
|
||||
|
||||
// func (api *ProductServerAPI) Create(value *sacloud.ProductServer) (*sacloud.ProductServer, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// Read 読み取り
|
||||
func (api *ProductServerAPI) Read(id int64) (*sacloud.ProductServer, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// func (api *ProductServerAPI) Update(id int64, value *sacloud.ProductServer) (*sacloud.ProductServer, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *ProductServerAPI) Delete(id int64) (*sacloud.ProductServer, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *ProductServerAPI) setStateValue(setFunc func(*sacloud.Request)) *ProductServerAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *ProductServerAPI) request(f func(*sacloud.Response) error) (*sacloud.ProductServer, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.ServerPlan, nil
|
||||
}
|
||||
|
||||
func (api *ProductServerAPI) createRequest(value *sacloud.ProductServer) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.ServerPlan = value
|
||||
return req
|
||||
}
|
18
vendor/github.com/sacloud/libsacloud/api/public_price.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/public_price.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// PublicPriceAPI 料金情報API
|
||||
type PublicPriceAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewPublicPriceAPI 料金情報API
|
||||
func NewPublicPriceAPI(client *Client) *PublicPriceAPI {
|
||||
return &PublicPriceAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "public/price"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
236
vendor/github.com/sacloud/libsacloud/api/public_price_gen.go
generated
vendored
Normal file
236
vendor/github.com/sacloud/libsacloud/api/public_price_gen.go
generated
vendored
Normal file
@ -0,0 +1,236 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [PublicPriceAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *PublicPriceAPI) Reset() *PublicPriceAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *PublicPriceAPI) Offset(offset int) *PublicPriceAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *PublicPriceAPI) Limit(limit int) *PublicPriceAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *PublicPriceAPI) Include(key string) *PublicPriceAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *PublicPriceAPI) Exclude(key string) *PublicPriceAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *PublicPriceAPI) FilterBy(key string, value interface{}) *PublicPriceAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *PublicPriceAPI) FilterMultiBy(key string, value interface{}) *PublicPriceAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件(DisplayName)
|
||||
func (api *PublicPriceAPI) WithNameLike(name string) *PublicPriceAPI {
|
||||
return api.FilterBy("DisplayName", name)
|
||||
}
|
||||
|
||||
//// WithTag
|
||||
//func (api *PublicPriceAPI) WithTag(tag string) *PublicPriceAPI {
|
||||
// return api.FilterBy("Tags.Name", tag)
|
||||
//}
|
||||
|
||||
//// WithTags
|
||||
//func (api *PublicPriceAPI) WithTags(tags []string) *PublicPriceAPI {
|
||||
// return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
//}
|
||||
|
||||
// func (api *PublicPriceAPI) WithSizeGib(size int) *PublicPriceAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *PublicPriceAPI) WithSharedScope() *PublicPriceAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *PublicPriceAPI) WithUserScope() *PublicPriceAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *PublicPriceAPI) SortBy(key string, reverse bool) *PublicPriceAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート(DisplayName)
|
||||
func (api *PublicPriceAPI) SortByName(reverse bool) *PublicPriceAPI {
|
||||
api.sortBy("DisplayName", reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *PublicPriceAPI) SortBySize(reverse bool) *PublicPriceAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *PublicPriceAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *PublicPriceAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *PublicPriceAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *PublicPriceAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *PublicPriceAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *PublicPriceAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *PublicPriceAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件(DisplayName)
|
||||
func (api *PublicPriceAPI) SetNameLike(name string) {
|
||||
api.FilterBy("DisplayName", name)
|
||||
}
|
||||
|
||||
//// SetTag
|
||||
//func (api *PublicPriceAPI) SetTag(tag string) {
|
||||
//}
|
||||
|
||||
//// SetTags
|
||||
//func (api *PublicPriceAPI) SetTags(tags []string) {
|
||||
//}
|
||||
|
||||
// func (api *PublicPriceAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *PublicPriceAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *PublicPriceAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *PublicPriceAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート(DisplayName)
|
||||
func (api *PublicPriceAPI) SetSortByName(reverse bool) {
|
||||
api.sortBy("DisplayName", reverse)
|
||||
}
|
||||
|
||||
// func (api *PublicPriceAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *PublicPriceAPI) New() *sacloud.PublicPrice {
|
||||
// return &sacloud.PublicPrice{}
|
||||
// }
|
||||
|
||||
// func (api *PublicPriceAPI) Create(value *sacloud.PublicPrice) (*sacloud.PublicPrice, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *PublicPriceAPI) Read(id int64) (*sacloud.PublicPrice, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *PublicPriceAPI) Update(id int64, value *sacloud.PublicPrice) (*sacloud.PublicPrice, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *PublicPriceAPI) Delete(id int64) (*sacloud.PublicPrice, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *PublicPriceAPI) setStateValue(setFunc func(*sacloud.Request)) *PublicPriceAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *PublicPriceAPI) request(f func(*sacloud.Response) error) (*sacloud.PublicPrice, error) {
|
||||
// res := &sacloud.Response{}
|
||||
// err := f(res)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return res.ServiceClass, nil
|
||||
//}
|
||||
//
|
||||
//func (api *PublicPriceAPI) createRequest(value *sacloud.PublicPrice) *sacloud.Request {
|
||||
// req := &sacloud.Request{}
|
||||
// req.ServiceClass = value
|
||||
// return req
|
||||
//}
|
18
vendor/github.com/sacloud/libsacloud/api/region.go
generated
vendored
Normal file
18
vendor/github.com/sacloud/libsacloud/api/region.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
package api
|
||||
|
||||
// RegionAPI リージョンAPI
|
||||
type RegionAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewRegionAPI リージョンAPI作成
|
||||
func NewRegionAPI(client *Client) *RegionAPI {
|
||||
return &RegionAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "region"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
239
vendor/github.com/sacloud/libsacloud/api/region_gen.go
generated
vendored
Normal file
239
vendor/github.com/sacloud/libsacloud/api/region_gen.go
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [RegionAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *RegionAPI) Reset() *RegionAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *RegionAPI) Offset(offset int) *RegionAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *RegionAPI) Limit(limit int) *RegionAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *RegionAPI) Include(key string) *RegionAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *RegionAPI) Exclude(key string) *RegionAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *RegionAPI) FilterBy(key string, value interface{}) *RegionAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *RegionAPI) FilterMultiBy(key string, value interface{}) *RegionAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *RegionAPI) WithNameLike(name string) *RegionAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
//// WithTag
|
||||
//func (api *RegionAPI) WithTag(tag string) *RegionAPI {
|
||||
// return api.FilterBy("Tags.Name", tag)
|
||||
//}
|
||||
//
|
||||
//// WithTags
|
||||
//func (api *RegionAPI) WithTags(tags []string) *RegionAPI {
|
||||
// return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
//}
|
||||
|
||||
// func (api *RegionAPI) WithSizeGib(size int) *RegionAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *RegionAPI) WithSharedScope() *RegionAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *RegionAPI) WithUserScope() *RegionAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *RegionAPI) SortBy(key string, reverse bool) *RegionAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *RegionAPI) SortByName(reverse bool) *RegionAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *RegionAPI) SortBySize(reverse bool) *RegionAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *RegionAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *RegionAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *RegionAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *RegionAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *RegionAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *RegionAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *RegionAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *RegionAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
//// SetTag
|
||||
//func (api *RegionAPI) SetTag(tag string) {
|
||||
// api.FilterBy("Tags.Name", tag)
|
||||
//}
|
||||
//
|
||||
//// SetTags
|
||||
//func (api *RegionAPI) SetTags(tags []string) {
|
||||
// api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
//}
|
||||
|
||||
// func (api *RegionAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *RegionAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *RegionAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *RegionAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *RegionAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *RegionAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
//func (api *RegionAPI) New() *sacloud.Region {
|
||||
// return &sacloud.Region{}
|
||||
//}
|
||||
|
||||
// func (api *RegionAPI) Create(value *sacloud.Region) (*sacloud.Region, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// Read 読み取り
|
||||
func (api *RegionAPI) Read(id int64) (*sacloud.Region, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// func (api *RegionAPI) Update(id int64, value *sacloud.Region) (*sacloud.Region, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *RegionAPI) Delete(id int64) (*sacloud.Region, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *RegionAPI) setStateValue(setFunc func(*sacloud.Request)) *RegionAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *RegionAPI) request(f func(*sacloud.Response) error) (*sacloud.Region, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Region, nil
|
||||
}
|
||||
|
||||
func (api *RegionAPI) createRequest(value *sacloud.Region) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.Region = value
|
||||
return req
|
||||
}
|
287
vendor/github.com/sacloud/libsacloud/api/server.go
generated
vendored
Normal file
287
vendor/github.com/sacloud/libsacloud/api/server.go
generated
vendored
Normal file
@ -0,0 +1,287 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ServerAPI サーバーAPI
|
||||
type ServerAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewServerAPI サーバーAPI作成
|
||||
func NewServerAPI(client *Client) *ServerAPI {
|
||||
return &ServerAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "server"
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// WithPlan サーバープラン条件
|
||||
func (api *ServerAPI) WithPlan(planID string) *ServerAPI {
|
||||
return api.FilterBy("ServerPlan.ID", planID)
|
||||
}
|
||||
|
||||
// WithStatus インスタンスステータス条件
|
||||
func (api *ServerAPI) WithStatus(status string) *ServerAPI {
|
||||
return api.FilterBy("Instance.Status", status)
|
||||
}
|
||||
|
||||
// WithStatusUp 起動状態条件
|
||||
func (api *ServerAPI) WithStatusUp() *ServerAPI {
|
||||
return api.WithStatus("up")
|
||||
}
|
||||
|
||||
// WithStatusDown ダウン状態条件
|
||||
func (api *ServerAPI) WithStatusDown() *ServerAPI {
|
||||
return api.WithStatus("down")
|
||||
}
|
||||
|
||||
// WithISOImage ISOイメージ条件
|
||||
func (api *ServerAPI) WithISOImage(imageID int64) *ServerAPI {
|
||||
return api.FilterBy("Instance.CDROM.ID", imageID)
|
||||
}
|
||||
|
||||
// SortByCPU CPUコア数でのソート
|
||||
func (api *ServerAPI) SortByCPU(reverse bool) *ServerAPI {
|
||||
api.sortBy("ServerPlan.CPU", reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByMemory メモリサイズでのソート
|
||||
func (api *ServerAPI) SortByMemory(reverse bool) *ServerAPI {
|
||||
api.sortBy("ServerPlan.MemoryMB", reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// DeleteWithDisk 指定のディスクと共に削除する
|
||||
func (api *ServerAPI) DeleteWithDisk(id int64, disks []int64) (*sacloud.Server, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, map[string]interface{}{"WithDisk": disks}, res)
|
||||
})
|
||||
}
|
||||
|
||||
// State ステータス(Availability)取得
|
||||
func (api *ServerAPI) State(id int64) (string, error) {
|
||||
server, err := api.Read(id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(server.Availability), nil
|
||||
}
|
||||
|
||||
// IsUp 起動しているか判定
|
||||
func (api *ServerAPI) IsUp(id int64) (bool, error) {
|
||||
server, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return server.Instance.IsUp(), nil
|
||||
}
|
||||
|
||||
// IsDown ダウンしているか判定
|
||||
func (api *ServerAPI) IsDown(id int64) (bool, error) {
|
||||
server, err := api.Read(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return server.Instance.IsDown(), nil
|
||||
}
|
||||
|
||||
// Boot 起動
|
||||
func (api *ServerAPI) Boot(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Shutdown シャットダウン(graceful)
|
||||
func (api *ServerAPI) Shutdown(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Stop シャットダウン(force)
|
||||
func (api *ServerAPI) Stop(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/power", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]bool{"Force": true})
|
||||
}
|
||||
|
||||
// RebootForce 再起動
|
||||
func (api *ServerAPI) RebootForce(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/reset", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// SleepUntilUp 起動するまで待機
|
||||
func (api *ServerAPI) SleepUntilUp(id int64, timeout time.Duration) error {
|
||||
handler := waitingForUpFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// SleepUntilDown ダウンするまで待機
|
||||
func (api *ServerAPI) SleepUntilDown(id int64, timeout time.Duration) error {
|
||||
handler := waitingForDownFunc(func() (hasUpDown, error) {
|
||||
return api.Read(id)
|
||||
}, 0)
|
||||
return blockingPoll(handler, timeout)
|
||||
}
|
||||
|
||||
// ChangePlan サーバープラン変更(サーバーIDが変更となるため注意)
|
||||
func (api *ServerAPI) ChangePlan(serverID int64, planID string) (*sacloud.Server, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/to/plan/%s", api.getResourceURL(), serverID, planID)
|
||||
)
|
||||
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.baseAPI.request(method, uri, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// FindDisk 指定サーバーに接続されているディスク一覧を取得
|
||||
func (api *ServerAPI) FindDisk(serverID int64) ([]sacloud.Disk, error) {
|
||||
server, err := api.Read(serverID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return server.Disks, nil
|
||||
}
|
||||
|
||||
// InsertCDROM ISOイメージを挿入
|
||||
func (api *ServerAPI) InsertCDROM(serverID int64, cdromID int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/cdrom", api.getResourceURL(), serverID)
|
||||
)
|
||||
|
||||
req := &sacloud.Request{
|
||||
SakuraCloudResources: sacloud.SakuraCloudResources{
|
||||
CDROM: &sacloud.CDROM{Resource: &sacloud.Resource{ID: cdromID}},
|
||||
},
|
||||
}
|
||||
|
||||
return api.modify(method, uri, req)
|
||||
}
|
||||
|
||||
// EjectCDROM ISOイメージを取り出し
|
||||
func (api *ServerAPI) EjectCDROM(serverID int64, cdromID int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/cdrom", api.getResourceURL(), serverID)
|
||||
)
|
||||
|
||||
req := &sacloud.Request{
|
||||
SakuraCloudResources: sacloud.SakuraCloudResources{
|
||||
CDROM: &sacloud.CDROM{Resource: &sacloud.Resource{ID: cdromID}},
|
||||
},
|
||||
}
|
||||
|
||||
return api.modify(method, uri, req)
|
||||
}
|
||||
|
||||
// NewKeyboardRequest キーボード入力リクエストパラメーター作成
|
||||
func (api *ServerAPI) NewKeyboardRequest() *sacloud.KeyboardRequest {
|
||||
return &sacloud.KeyboardRequest{}
|
||||
}
|
||||
|
||||
// SendKey キーボード入力送信
|
||||
func (api *ServerAPI) SendKey(serverID int64, body *sacloud.KeyboardRequest) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/keyboard", api.getResourceURL(), serverID)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, body)
|
||||
}
|
||||
|
||||
// NewMouseRequest マウス入力リクエストパラメーター作成
|
||||
func (api *ServerAPI) NewMouseRequest() *sacloud.MouseRequest {
|
||||
return &sacloud.MouseRequest{
|
||||
Buttons: &sacloud.MouseRequestButtons{},
|
||||
}
|
||||
}
|
||||
|
||||
// SendMouse マウス入力送信
|
||||
func (api *ServerAPI) SendMouse(serverID int64, mouseIndex string, body *sacloud.MouseRequest) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/mouse/%s", api.getResourceURL(), serverID, mouseIndex)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, body)
|
||||
}
|
||||
|
||||
// NewVNCSnapshotRequest VNCスナップショット取得リクエストパラメーター作成
|
||||
func (api *ServerAPI) NewVNCSnapshotRequest() *sacloud.VNCSnapshotRequest {
|
||||
return &sacloud.VNCSnapshotRequest{}
|
||||
}
|
||||
|
||||
// GetVNCProxy VNCプロキシ情報取得
|
||||
func (api *ServerAPI) GetVNCProxy(serverID int64) (*sacloud.VNCProxyResponse, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/vnc/proxy", api.getResourceURL(), serverID)
|
||||
res = &sacloud.VNCProxyResponse{}
|
||||
)
|
||||
err := api.baseAPI.request(method, uri, nil, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// GetVNCSize VNC画面サイズ取得
|
||||
func (api *ServerAPI) GetVNCSize(serverID int64) (*sacloud.VNCSizeResponse, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/vnc/size", api.getResourceURL(), serverID)
|
||||
res = &sacloud.VNCSizeResponse{}
|
||||
)
|
||||
err := api.baseAPI.request(method, uri, nil, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// GetVNCSnapshot VNCスナップショット取得
|
||||
func (api *ServerAPI) GetVNCSnapshot(serverID int64, body *sacloud.VNCSnapshotRequest) (*sacloud.VNCSnapshotResponse, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/vnc/snapshot", api.getResourceURL(), serverID)
|
||||
res = &sacloud.VNCSnapshotResponse{}
|
||||
)
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Monitor アクティビティーモニター(CPU-TIME)取得
|
||||
func (api *ServerAPI) Monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
return api.baseAPI.monitor(id, body)
|
||||
}
|
243
vendor/github.com/sacloud/libsacloud/api/server_gen.go
generated
vendored
Normal file
243
vendor/github.com/sacloud/libsacloud/api/server_gen.go
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [ServerAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *ServerAPI) Reset() *ServerAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *ServerAPI) Offset(offset int) *ServerAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *ServerAPI) Limit(limit int) *ServerAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *ServerAPI) Include(key string) *ServerAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *ServerAPI) Exclude(key string) *ServerAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *ServerAPI) FilterBy(key string, value interface{}) *ServerAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ServerAPI) FilterMultiBy(key string, value interface{}) *ServerAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *ServerAPI) WithNameLike(name string) *ServerAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *ServerAPI) WithTag(tag string) *ServerAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *ServerAPI) WithTags(tags []string) *ServerAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ServerAPI) WithSizeGib(size int) *ServerAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ServerAPI) WithSharedScope() *ServerAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *ServerAPI) WithUserScope() *ServerAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *ServerAPI) SortBy(key string, reverse bool) *ServerAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *ServerAPI) SortByName(reverse bool) *ServerAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *ServerAPI) SortBySize(reverse bool) *ServerAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *ServerAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *ServerAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *ServerAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *ServerAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *ServerAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *ServerAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *ServerAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *ServerAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *ServerAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *ServerAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *ServerAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *ServerAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *ServerAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *ServerAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *ServerAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *ServerAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *ServerAPI) New() *sacloud.Server {
|
||||
return &sacloud.Server{}
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *ServerAPI) Create(value *sacloud.Server) (*sacloud.Server, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *ServerAPI) Read(id int64) (*sacloud.Server, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *ServerAPI) Update(id int64, value *sacloud.Server) (*sacloud.Server, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *ServerAPI) Delete(id int64) (*sacloud.Server, error) {
|
||||
return api.request(func(res *sacloud.Response) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *ServerAPI) setStateValue(setFunc func(*sacloud.Request)) *ServerAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *ServerAPI) request(f func(*sacloud.Response) error) (*sacloud.Server, error) {
|
||||
res := &sacloud.Response{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Server, nil
|
||||
}
|
||||
|
||||
func (api *ServerAPI) createRequest(value *sacloud.Server) *sacloud.Request {
|
||||
req := &sacloud.Request{}
|
||||
req.Server = value
|
||||
return req
|
||||
}
|
219
vendor/github.com/sacloud/libsacloud/api/sim.go
generated
vendored
Normal file
219
vendor/github.com/sacloud/libsacloud/api/sim.go
generated
vendored
Normal file
@ -0,0 +1,219 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
// SearchSIMResponse SIM検索レスポンス
|
||||
type SearchSIMResponse struct {
|
||||
// Total 総件数
|
||||
Total int `json:",omitempty"`
|
||||
// From ページング開始位置
|
||||
From int `json:",omitempty"`
|
||||
// Count 件数
|
||||
Count int `json:",omitempty"`
|
||||
// CommonServiceSIMItems SIMリスト
|
||||
CommonServiceSIMItems []sacloud.SIM `json:"CommonServiceItems,omitempty"`
|
||||
}
|
||||
|
||||
type simRequest struct {
|
||||
CommonServiceSIMItem *sacloud.SIM `json:"CommonServiceItem,omitempty"`
|
||||
From int `json:",omitempty"`
|
||||
Count int `json:",omitempty"`
|
||||
Sort []string `json:",omitempty"`
|
||||
Filter map[string]interface{} `json:",omitempty"`
|
||||
Exclude []string `json:",omitempty"`
|
||||
Include []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type simResponse struct {
|
||||
*sacloud.ResultFlagValue
|
||||
*sacloud.SIM `json:"CommonServiceItem,omitempty"`
|
||||
}
|
||||
|
||||
type simLogResponse struct {
|
||||
Logs []sacloud.SIMLog `json:"logs,omitempty"`
|
||||
IsOk bool `json:"is_ok,omitempty"`
|
||||
}
|
||||
|
||||
// SIMAPI SIM API
|
||||
type SIMAPI struct {
|
||||
*baseAPI
|
||||
}
|
||||
|
||||
// NewSIMAPI SIM API作成
|
||||
func NewSIMAPI(client *Client) *SIMAPI {
|
||||
return &SIMAPI{
|
||||
&baseAPI{
|
||||
client: client,
|
||||
FuncGetResourceURL: func() string {
|
||||
return "commonserviceitem"
|
||||
},
|
||||
FuncBaseSearchCondition: func() *sacloud.Request {
|
||||
res := &sacloud.Request{}
|
||||
res.AddFilter("Provider.Class", "sim")
|
||||
return res
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Find 検索
|
||||
func (api *SIMAPI) Find() (*SearchSIMResponse, error) {
|
||||
|
||||
data, err := api.client.newRequest("GET", api.getResourceURL(), api.getSearchState())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res SearchSIMResponse
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (api *SIMAPI) request(f func(*simResponse) error) (*sacloud.SIM, error) {
|
||||
res := &simResponse{}
|
||||
err := f(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.SIM, nil
|
||||
}
|
||||
|
||||
func (api *SIMAPI) createRequest(value *sacloud.SIM) *simRequest {
|
||||
req := &simRequest{}
|
||||
req.CommonServiceSIMItem = value
|
||||
return req
|
||||
}
|
||||
|
||||
// Create 新規作成
|
||||
func (api *SIMAPI) Create(value *sacloud.SIM) (*sacloud.SIM, error) {
|
||||
return api.request(func(res *simResponse) error {
|
||||
return api.create(api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// New 新規作成用パラメーター作成
|
||||
func (api *SIMAPI) New(name, iccID, passcode string) *sacloud.SIM {
|
||||
return sacloud.CreateNewSIM(name, iccID, passcode)
|
||||
}
|
||||
|
||||
// Read 読み取り
|
||||
func (api *SIMAPI) Read(id int64) (*sacloud.SIM, error) {
|
||||
return api.request(func(res *simResponse) error {
|
||||
return api.read(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Update 更新
|
||||
func (api *SIMAPI) Update(id int64, value *sacloud.SIM) (*sacloud.SIM, error) {
|
||||
return api.request(func(res *simResponse) error {
|
||||
return api.update(id, api.createRequest(value), res)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete 削除
|
||||
func (api *SIMAPI) Delete(id int64) (*sacloud.SIM, error) {
|
||||
return api.request(func(res *simResponse) error {
|
||||
return api.delete(id, nil, res)
|
||||
})
|
||||
}
|
||||
|
||||
// Activate SIM有効化
|
||||
func (api *SIMAPI) Activate(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/sim/activate", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Deactivate SIM無効化
|
||||
func (api *SIMAPI) Deactivate(id int64) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/sim/deactivate", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// AssignIP SIMへのIP割り当て
|
||||
func (api *SIMAPI) AssignIP(id int64, ip string) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/sim/ip", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]interface{}{
|
||||
"sim": map[string]interface{}{
|
||||
"ip": ip,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// ClearIP SIMからのIP割り当て解除
|
||||
func (api *SIMAPI) ClearIP(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/sim/ip", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// IMEILock IMEIロック
|
||||
func (api *SIMAPI) IMEILock(id int64, imei string) (bool, error) {
|
||||
var (
|
||||
method = "PUT"
|
||||
uri = fmt.Sprintf("%s/%d/sim/imeilock", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
return api.modify(method, uri, map[string]interface{}{
|
||||
"sim": map[string]interface{}{
|
||||
"imei": imei,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// IMEIUnlock IMEIアンロック
|
||||
func (api *SIMAPI) IMEIUnlock(id int64) (bool, error) {
|
||||
var (
|
||||
method = "DELETE"
|
||||
uri = fmt.Sprintf("%s/%d/sim/imeilock", api.getResourceURL(), id)
|
||||
)
|
||||
return api.modify(method, uri, nil)
|
||||
}
|
||||
|
||||
// Logs セッションログ取得
|
||||
func (api *SIMAPI) Logs(id int64, body interface{}) ([]sacloud.SIMLog, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/sim/sessionlog", api.getResourceURL(), id)
|
||||
)
|
||||
|
||||
res := &simLogResponse{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Logs, nil
|
||||
}
|
||||
|
||||
// Monitor アクティビティーモニター(Up/Down link BPS)取得
|
||||
func (api *SIMAPI) Monitor(id int64, body *sacloud.ResourceMonitorRequest) (*sacloud.MonitorValues, error) {
|
||||
var (
|
||||
method = "GET"
|
||||
uri = fmt.Sprintf("%s/%d/sim/metrics", api.getResourceURL(), id)
|
||||
)
|
||||
res := &sacloud.ResourceMonitorResponse{}
|
||||
err := api.baseAPI.request(method, uri, body, res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Data, nil
|
||||
}
|
238
vendor/github.com/sacloud/libsacloud/api/sim_gen.go
generated
vendored
Normal file
238
vendor/github.com/sacloud/libsacloud/api/sim_gen.go
generated
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
package api
|
||||
|
||||
/************************************************
|
||||
generated by IDE. for [SIMAPI]
|
||||
************************************************/
|
||||
|
||||
import (
|
||||
"github.com/sacloud/libsacloud/sacloud"
|
||||
)
|
||||
|
||||
/************************************************
|
||||
To support fluent interface for Find()
|
||||
************************************************/
|
||||
|
||||
// Reset 検索条件のリセット
|
||||
func (api *SIMAPI) Reset() *SIMAPI {
|
||||
api.reset()
|
||||
return api
|
||||
}
|
||||
|
||||
// Offset オフセット
|
||||
func (api *SIMAPI) Offset(offset int) *SIMAPI {
|
||||
api.offset(offset)
|
||||
return api
|
||||
}
|
||||
|
||||
// Limit リミット
|
||||
func (api *SIMAPI) Limit(limit int) *SIMAPI {
|
||||
api.limit(limit)
|
||||
return api
|
||||
}
|
||||
|
||||
// Include 取得する項目
|
||||
func (api *SIMAPI) Include(key string) *SIMAPI {
|
||||
api.include(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// Exclude 除外する項目
|
||||
func (api *SIMAPI) Exclude(key string) *SIMAPI {
|
||||
api.exclude(key)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterBy 指定キーでのフィルター
|
||||
func (api *SIMAPI) FilterBy(key string, value interface{}) *SIMAPI {
|
||||
api.filterBy(key, value, false)
|
||||
return api
|
||||
}
|
||||
|
||||
// FilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *SIMAPI) FilterMultiBy(key string, value interface{}) *SIMAPI {
|
||||
api.filterBy(key, value, true)
|
||||
return api
|
||||
}
|
||||
|
||||
// WithNameLike 名称条件
|
||||
func (api *SIMAPI) WithNameLike(name string) *SIMAPI {
|
||||
return api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// WithTag タグ条件
|
||||
func (api *SIMAPI) WithTag(tag string) *SIMAPI {
|
||||
return api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// WithTags タグ(複数)条件
|
||||
func (api *SIMAPI) WithTags(tags []string) *SIMAPI {
|
||||
return api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *SIMAPI) WithSizeGib(size int) *SIMAPI {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *SIMAPI) WithSharedScope() *SIMAPI {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// func (api *SIMAPI) WithUserScope() *SIMAPI {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// return api
|
||||
// }
|
||||
|
||||
// SortBy 指定キーでのソート
|
||||
func (api *SIMAPI) SortBy(key string, reverse bool) *SIMAPI {
|
||||
api.sortBy(key, reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// SortByName 名称でのソート
|
||||
func (api *SIMAPI) SortByName(reverse bool) *SIMAPI {
|
||||
api.sortByName(reverse)
|
||||
return api
|
||||
}
|
||||
|
||||
// func (api *SIMAPI) SortBySize(reverse bool) *SIMAPI {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// return api
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support Setxxx interface for Find()
|
||||
************************************************/
|
||||
|
||||
// SetEmpty 検索条件のリセット
|
||||
func (api *SIMAPI) SetEmpty() {
|
||||
api.reset()
|
||||
}
|
||||
|
||||
// SetOffset オフセット
|
||||
func (api *SIMAPI) SetOffset(offset int) {
|
||||
api.offset(offset)
|
||||
}
|
||||
|
||||
// SetLimit リミット
|
||||
func (api *SIMAPI) SetLimit(limit int) {
|
||||
api.limit(limit)
|
||||
}
|
||||
|
||||
// SetInclude 取得する項目
|
||||
func (api *SIMAPI) SetInclude(key string) {
|
||||
api.include(key)
|
||||
}
|
||||
|
||||
// SetExclude 除外する項目
|
||||
func (api *SIMAPI) SetExclude(key string) {
|
||||
api.exclude(key)
|
||||
}
|
||||
|
||||
// SetFilterBy 指定キーでのフィルター
|
||||
func (api *SIMAPI) SetFilterBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, false)
|
||||
}
|
||||
|
||||
// SetFilterMultiBy 任意項目でのフィルタ(完全一致 OR条件)
|
||||
func (api *SIMAPI) SetFilterMultiBy(key string, value interface{}) {
|
||||
api.filterBy(key, value, true)
|
||||
}
|
||||
|
||||
// SetNameLike 名称条件
|
||||
func (api *SIMAPI) SetNameLike(name string) {
|
||||
api.FilterBy("Name", name)
|
||||
}
|
||||
|
||||
// SetTag タグ条件
|
||||
func (api *SIMAPI) SetTag(tag string) {
|
||||
api.FilterBy("Tags.Name", tag)
|
||||
}
|
||||
|
||||
// SetTags タグ(複数)条件
|
||||
func (api *SIMAPI) SetTags(tags []string) {
|
||||
api.FilterBy("Tags.Name", []interface{}{tags})
|
||||
}
|
||||
|
||||
// func (api *SIMAPI) SetSizeGib(size int) {
|
||||
// api.FilterBy("SizeMB", size*1024)
|
||||
// }
|
||||
|
||||
// func (api *SIMAPI) SetSharedScope() {
|
||||
// api.FilterBy("Scope", "shared")
|
||||
// }
|
||||
|
||||
// func (api *SIMAPI) SetUserScope() {
|
||||
// api.FilterBy("Scope", "user")
|
||||
// }
|
||||
|
||||
// SetSortBy 指定キーでのソート
|
||||
func (api *SIMAPI) SetSortBy(key string, reverse bool) {
|
||||
api.sortBy(key, reverse)
|
||||
}
|
||||
|
||||
// SetSortByName 名称でのソート
|
||||
func (api *SIMAPI) SetSortByName(reverse bool) {
|
||||
api.sortByName(reverse)
|
||||
}
|
||||
|
||||
// func (api *SIMAPI) SetSortBySize(reverse bool) {
|
||||
// api.sortBy("SizeMB", reverse)
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
To support CRUD(Create/Read/Update/Delete)
|
||||
************************************************/
|
||||
|
||||
// func (api *SIMAPI) New() *sacloud.SIM {
|
||||
// return &sacloud.SIM{}
|
||||
// }
|
||||
|
||||
// func (api *SIMAPI) Create(value *sacloud.SIM) (*sacloud.SIM, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.create(api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *SIMAPI) Read(id string) (*sacloud.SIM, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.read(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *SIMAPI) Update(id string, value *sacloud.SIM) (*sacloud.SIM, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.update(id, api.createRequest(value), res)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func (api *SIMAPI) Delete(id string) (*sacloud.SIM, error) {
|
||||
// return api.request(func(res *sacloud.Response) error {
|
||||
// return api.delete(id, nil, res)
|
||||
// })
|
||||
// }
|
||||
|
||||
/************************************************
|
||||
Inner functions
|
||||
************************************************/
|
||||
|
||||
func (api *SIMAPI) setStateValue(setFunc func(*sacloud.Request)) *SIMAPI {
|
||||
api.baseAPI.setStateValue(setFunc)
|
||||
return api
|
||||
}
|
||||
|
||||
//func (api *SIMAPI) request(f func(*sacloud.Response) error) (*sacloud.SIM, error) {
|
||||
// res := &sacloud.Response{}
|
||||
// err := f(res)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return res.SIM, nil
|
||||
//}
|
||||
//
|
||||
//func (api *SIMAPI) createRequest(value *sacloud.SIM) *simRequest {
|
||||
// req := &simRequest{}
|
||||
// req.CommonServiceSIMItem = value
|
||||
// return req
|
||||
//}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user