1
0
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:
Ludovic Fernandez 2018-07-03 12:44:04 +02:00 committed by Traefiker Bot
parent 17ad5153b8
commit 139f280f35
258 changed files with 25528 additions and 1516 deletions

26
Gopkg.lock generated
View File

@ -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

View File

@ -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)

View File

@ -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)
}

View 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
}

View File

@ -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
}

View File

@ -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

View File

@ -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.
@ -203,7 +259,7 @@ Here is a list of supported `provider`s, that can automate the DNS verification,
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | Not tested yet |
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | Not tested yet |
| External Program | `exec` | `EXEC_PATH` | Not tested yet |
| [Exoscale](https://www.exoscale.ch) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | YES |
| [Exoscale](https://www.exoscale.ch) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | YES |
| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | Not tested yet |
| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | Not tested yet |
| [Gandi V5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | YES |
@ -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"

View File

@ -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,268 +15,360 @@ 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(),
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnHostRule: true,
Domains: types.Domains{types.Domain{
Main: "traefik.acme.wtf",
}},
template: templateModel{
Acme: acme.Configuration{
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
Domains: types.Domains{types.Domain{
Main: "traefik.acme.wtf",
}},
},
},
expectedDomain: acmeDomain,
expectedAlgorithm: x509.RSA,
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(),
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
Domains: types.Domains{types.Domain{
Main: "acme.wtf",
SANs: []string{"traefik.acme.wtf"},
}},
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",
expectedAlgorithm: x509.RSA,
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{
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
CAServer: s.getAcmeURL(),
OnHostRule: true,
template: templateModel{
Acme: acme.Configuration{
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnHostRule: true,
},
},
expectedDomain: acmeDomain,
expectedAlgorithm: x509.RSA,
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(),
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnHostRule: true,
KeyType: "EC384",
template: templateModel{
Acme: acme.Configuration{
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnHostRule: true,
KeyType: "EC384",
},
},
expectedDomain: acmeDomain,
expectedAlgorithm: x509.ECDSA,
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(),
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnHostRule: true,
KeyType: "INVALID",
template: templateModel{
Acme: acme.Configuration{
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnHostRule: true,
KeyType: "INVALID",
},
},
expectedDomain: acmeDomain,
expectedAlgorithm: x509.RSA,
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(),
OnHostRule: true,
},
expectedDomain: traefikDefaultDomain,
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{
traefikConfFilePath: "fixtures/acme/acme-base.toml",
configuration: acme.Configuration{
CAServer: s.getAcmeURL(),
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,
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{
func (s *AcmeSuite) TestHTTP01OnHostRuleWithPath(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,
template: templateModel{
Acme: acme.Configuration{
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnHostRule: true,
},
},
expectedDomain: acmeDomain,
expectedAlgorithm: x509.RSA,
expectedCommonName: 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) 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",
template: templateModel{
Acme: acme.Configuration{
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnDemand: true,
},
},
expectedCommonName: acmeDomain,
expectedAlgorithm: x509.RSA,
}
s.retrieveAcmeCertificate(c, testCase)
}
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(),
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnDemand: true,
template: templateModel{
Acme: acme.Configuration{
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnDemand: true,
},
},
expectedDomain: wildcardDomain,
expectedAlgorithm: x509.RSA,
expectedCommonName: 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,
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(),
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnDemand: true,
template: templateModel{
Acme: acme.Configuration{
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnDemand: true,
},
},
expectedDomain: wildcardDomain,
expectedAlgorithm: x509.RSA,
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"},
OnHostRule: true,
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,
expectedAlgorithm: x509.RSA,
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,
}
s.retrieveAcmeCertificate(c, testCase)
@ -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{
CAServer: "http://wrongurl:4001/directory",
HTTPChallenge: &acme.HTTPChallenge{EntryPoint: "http"},
OnHostRule: true,
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)
}

View 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
}

View File

@ -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 }}

View File

@ -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 }}

View File

@ -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 }}

View File

@ -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 }}

View 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-----

View File

@ -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

View 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

View File

@ -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
}
}

View File

@ -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)
if httpChallenges == nil {
httpChallenges = map[string]map[string][]byte{}
}
acme.PreCheckDNS = func(_, _ string) (bool, error) {
time.Sleep(time.Duration(delay))
return true, nil
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)
}
} else {
return fmt.Errorf("delayBeforeCheck: %d cannot be less than 0", delay)
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()
if err != nil {
return fmt.Errorf("unable to get HTTPChallenges : %s", err)
}
// 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
}
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()
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 store.SaveHTTPChallenges(httpChallenges)
}
return nil
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)
}))
}

View 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
}

View File

@ -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
}

View File

@ -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) {
// 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 {
return err
}
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, 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 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
}
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:]
}
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)
}
})
}
}
}
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)
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
}
// 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()
if err != nil {
return err
}
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, 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) {
func (p *Provider) watchNewDomains() {
p.pool.Go(func(stop chan bool) {
for {
select {
case <-ticker.C:
p.renewCertificates()
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
}
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:]
}
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)
}
})
}
}
}
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
}

View File

@ -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
}

View File

@ -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")

View File

@ -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)
jsonConf, _ := json.Marshal(configMsg.Configuration)
log.Debugf("Configuration received from provider %s: %s", configMsg.ProviderName, string(jsonConf))
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

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
}

View 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
View 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)
})
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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)
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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)
}

View 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
View 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)
}

View 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
View 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)
})
}

View 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
View 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)
})
}

View 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
View 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
View 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
View 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
View 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
}

View 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)
}

View 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
//}

View 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
}

View 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
View 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
View 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
View 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
View 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
View 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
}

View 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"
},
},
}
}

View 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
View 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
}
}

View 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"
},
},
}
}

View 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
}

View 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"
},
},
}
}

View 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
}

View 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"
},
},
}
}

View 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
}

View 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"
},
},
}
}

View 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
}

View 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"
},
},
}
}

View 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
}

View 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
}

View 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
}

View 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"
},
},
}
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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